Ejemplo n.º 1
0
		/// <summary>
		/// 扫描 '\'(不包含 '\' 本身)之后的字符,并返回相应的正则表达式。
		/// </summary>
		/// <returns>相应的正则表达式。</returns>
		private Regex ScanBackslash()
		{
			RegexCharClass cc;
			int ich;
			switch (ich = reader.Read())
			{
				case 'w':
					return Regex.CharClass(
						UseOptionEcma ? RegexCharClass.EcmaWordClass : RegexCharClass.WordClass);
				case 'W':
					return Regex.CharClass(
						UseOptionEcma ? RegexCharClass.NotEcmaWordClass : RegexCharClass.NotWordClass);
				case 's':
					return Regex.CharClass(
						UseOptionEcma ? RegexCharClass.EcmaSpaceClass : RegexCharClass.SpaceClass);
				case 'S':
					return Regex.CharClass(
						UseOptionEcma ? RegexCharClass.NotEcmaSpaceClass : RegexCharClass.NotSpaceClass);
				case 'd':
					return Regex.CharClass(
						UseOptionEcma ? RegexCharClass.EcmaDigitClass : RegexCharClass.DigitClass);
				case 'D':
					return Regex.CharClass(
						UseOptionEcma ? RegexCharClass.NotEcmaDigitClass : RegexCharClass.NotDigitClass);
				case 'p':
				case 'P':
					cc = new RegexCharClass();
					cc.AddCategoryFromName(ScanProperty(), ich != 'p', UseOptionIgnoreCase, pattern);
					if (UseOptionIgnoreCase)
					{
						cc.AddLowercase(culture);
					}
					return Regex.CharClass(cc.ToStringClass());
				case -1:
					ThrowIllegalEndEscape();
					return null;
				default:
					reader.Unget();
					char ch = ScanCharEscape();
					if (UseOptionIgnoreCase)
					{
						return Regex.SymbolIgnoreCase(ch, culture);
					}
					else
					{
						return Regex.Symbol(ch);
					}
			}
		}
Ejemplo n.º 2
0
		private RegexCharClass ScanCharClass(bool closeBracket)
		{
			RegexCharClass rcc = new RegexCharClass();
			// 是否正在定义字符范围。
			bool inRange = false;
			// 是否是首字符。
			bool firstChar = true;
			// [] 集合是否闭合。
			bool closed = false;
			// 否定的字符类。
			if (reader.Peek() == '^')
			{
				reader.Read();
				rcc.Negate = true;
			}
			int ich = '\0';
			char chPrev = '\0';
			for (; (ich = reader.Read()) >= 0; firstChar = false)
			{
				// 当前字符时候是由转义得到的。
				bool escapedChar = false;
				if (ich == ']')
				{
					// [ 之后的第一个 ] 认为是字符 ]。
					if (!firstChar)
					{
						// 闭合字符类。
						closed = true;
						break;
					}
				}
				else if (ich == '\\' && reader.Peek() >= 0)
				{
					// 判断 '\' 字符的转义。
					ich = ScanBackslash(rcc, inRange);
					if (ich == -1)
					{
						continue;
					}
				}
				if (inRange)
				{
					inRange = false;
					if (ich == '[' && !escapedChar && !firstChar)
					{
						// 本来认为在定义字符范围,但实际在定义一个减去范围。
						// 所以,需要将 chPrev 添加到字符类中,跳过 [ 符号,并递归的扫描新的字符类。
						rcc.AddChar(chPrev);
						rcc.AddSubtraction(ScanCharClass(true));
						if (reader.Peek() >= 0 && reader.Peek() != ']')
						{
							ThrowSubtractionMustBeLast();
						}
					}
					else
					{
						// 规则的字符范围,类似于 a-z。
						if (chPrev > ich)
						{
							ThrowReversedCharRange();
						}
						rcc.AddRange(chPrev, (char)ich);
					}
				}
				else
				{
					if (reader.Peek() == '-')
					{
						reader.Read();
						if (reader.Peek() >= 0 && reader.Peek() != ']')
						{
							// -] 中的,'-' 会按连字符处理。
							// 否则的话,认为是字符范围的起始。
							chPrev = (char)ich;
							inRange = true;
						}
						else
						{
							reader.Unget();
						}
					}
					if (!inRange)
					{
						if (ich == '-' && reader.Peek() == '[' && !escapedChar && !firstChar)
						{
							// 不在字符范围中,并且开始一个减去范围的定义,
							// 一般是由于减去范围紧跟着一个字符范围,例如 [a-z-[b]]。
							reader.Read();
							rcc.AddSubtraction(ScanCharClass(true));
							if (reader.Peek() >= 0 && reader.Peek() != ']')
							{
								ThrowSubtractionMustBeLast();
							}
						}
						else
						{
							rcc.AddRange((char)ich, (char)ich);
						}
					}
				}
			}
			reader.Drop();
			// 模式字符串已到达结尾也按闭合处理。
			if (!closed && closeBracket)
			{
				ThrowUnterminatedBracket();
			}
			if (UseOptionIgnoreCase)
			{
				rcc.AddLowercase(culture);
				rcc.AddUppercase(culture);
			}
			return rcc;
		}