RegexGenerator.Parser.cs (20)
141RegexOptions regexOptions = options is not null ? (RegexOptions)options : RegexOptions.None;
150RegexOptions regexOptionsWithPatternOptions;
160if ((regexOptionsWithPatternOptions & RegexOptions.IgnoreCase) != 0 && !string.IsNullOrEmpty(cultureName))
162if ((regexOptions & RegexOptions.CultureInvariant) != 0)
179const RegexOptions SupportedOptions =
180RegexOptions.Compiled |
181RegexOptions.CultureInvariant |
182RegexOptions.ECMAScript |
183RegexOptions.ExplicitCapture |
184RegexOptions.IgnoreCase |
185RegexOptions.IgnorePatternWhitespace |
186RegexOptions.Multiline |
187RegexOptions.NonBacktracking |
188RegexOptions.RightToLeft |
189RegexOptions.Singleline |
190RegexOptions.AnyNewLine;
253internal sealed record RegexPatternAndSyntax(RegexType DeclaringType, bool IsProperty, Location DiagnosticLocation, string MemberName, string Modifiers, bool NullableRegex, string Pattern, RegexOptions Options, int? MatchTimeout, CultureInfo Culture, CompilationData CompilationData);
256internal sealed record RegexMethod(RegexType DeclaringType, bool IsProperty, string MemberName, string Modifiers, bool NullableRegex, string Pattern, RegexOptions Options, int? MatchTimeout, RegexTree Tree, AnalysisResults Analysis, CompilationData CompilationData)
src\runtime\src\libraries\System.Text.RegularExpressions\src\System\Text\RegularExpressions\RegexNode.cs (54)
42public RegexOptions Options;
51public RegexNode(RegexNodeKind kind, RegexOptions options)
57public RegexNode(RegexNodeKind kind, RegexOptions options, char ch)
64public RegexNode(RegexNodeKind kind, RegexOptions options, string str)
71public RegexNode(RegexNodeKind kind, RegexOptions options, int m)
78public RegexNode(RegexNodeKind kind, RegexOptions options, int m, int n)
110public static RegexNode CreateOneWithCaseConversion(char ch, RegexOptions options, CultureInfo? culture, ref RegexCaseBehavior caseBehavior)
113if ((options & RegexOptions.IgnoreCase) != 0)
121return new RegexNode(RegexNodeKind.One, options & ~RegexOptions.IgnoreCase, ch);
127return new RegexNode(RegexNodeKind.Set, options & ~RegexOptions.IgnoreCase, stringSet);
137if ((Options & RegexOptions.RightToLeft) != 0 &&
355Debug.Assert((node.Options & RegexOptions.IgnoreCase) == 0, $"{node.Kind} node should not have RegexOptions.IgnoreCase");
379if ((rootNode.Options & (RegexOptions.RightToLeft | RegexOptions.NonBacktracking)) == 0)
400if ((rootNode.Options & RegexOptions.Compiled) != 0)
501(Options & RegexOptions.NonBacktracking) != 0)
516bool rtl = (node.Options & RegexOptions.RightToLeft) != 0;
628Options &= ~RegexOptions.IgnoreCase;
699if ((Options & RegexOptions.NonBacktracking) != 0)
751if ((Options & RegexOptions.RightToLeft) == 0)
1126RegexOptions optionsLast = 0;
1127RegexOptions optionsAt;
1164optionsAt = at.Options & (RegexOptions.RightToLeft | RegexOptions.IgnoreCase);
1212if ((prev.Options & RegexOptions.IgnoreCase) != 0)
1214prev.Options &= ~RegexOptions.IgnoreCase;
1246if ((alternation.Options & RegexOptions.RightToLeft) != 0)
1396if ((alternation.Options & RegexOptions.RightToLeft) != 0)
1412RegexOptions startingNodeOptions = startingNode.Options;
1558Debug.Assert((Options & RegexOptions.RightToLeft) == 0);
1573Debug.Assert((Options & RegexOptions.RightToLeft) == 0);
1638if (node is not null && (node.Options & RegexOptions.RightToLeft) == 0)
1788RegexOptions optionsLast = 0;
1802((at.Options & RegexOptions.RightToLeft) == (Options & RegexOptions.RightToLeft)))
1823RegexOptions optionsAt = at.Options & (RegexOptions.RightToLeft | RegexOptions.IgnoreCase);
1840prev.Str = (optionsAt & RegexOptions.RightToLeft) == 0 ?
1949(nextNode.Options & RegexOptions.RightToLeft) == 0 && // RTL multi nodes don't have their text reversed, and it's not worth the code to optimize further
2050Debug.Assert((Options & RegexOptions.NonBacktracking) == 0, "Atomic groups aren't supported and don't help performance with NonBacktracking");
2085(node.Options & RegexOptions.RightToLeft) != 0)
2277if (((Options & RegexOptions.RightToLeft) == 0 && IsZeroWidthAssertion(child.Kind)) ||
2377if (condition.Kind == RegexNodeKind.PositiveLookaround && (condition.Options & RegexOptions.RightToLeft) == 0)
2494case RegexNodeKind.PositiveLookaround when (subsequent.Options & RegexOptions.RightToLeft) == 0:
2793if ((node.Options & RegexOptions.RightToLeft) != 0 ||
3406if ((Options & RegexOptions.NonBacktracking) != 0)
3497if ((Options & RegexOptions.ExplicitCapture) != 0) sb.Append("-C");
3498if ((Options & RegexOptions.IgnoreCase) != 0) sb.Append("-I");
3499if ((Options & RegexOptions.RightToLeft) != 0) sb.Append("-L");
3500if ((Options & RegexOptions.Multiline) != 0) sb.Append("-M");
3501if ((Options & RegexOptions.Singleline) != 0) sb.Append("-S");
3502if ((Options & RegexOptions.IgnorePatternWhitespace) != 0) sb.Append("-X");
3503if ((Options & RegexOptions.ECMAScript) != 0) sb.Append("-E");
src\runtime\src\libraries\System.Text.RegularExpressions\src\System\Text\RegularExpressions\RegexNodeKind.cs (14)
18/// <summary>Anything other than a specific character, e.g. `.` when not in <see cref="RegexOptions.Singleline"/> mode, or `[^a]`.</summary>
35/// <summary>A loop around anything other than a specific character, e.g. `.*` when not in <see cref="RegexOptions.Singleline"/> mode, or `[^a]*`.</summary>
48/// <summary>A lazy loop around anything other than a specific character, e.g. `.*?` when not in <see cref="RegexOptions.Singleline"/> mode, or `[^a]*?`.</summary>
63/// <summary>An atomic loop around anything other than a specific character, e.g. `(?>.*)` when not in <see cref="RegexOptions.Singleline"/> mode.</summary>
80/// <summary>A beginning-of-line anchor, e.g. `^` in <see cref="RegexOptions.Multiline"/> mode.</summary>
82/// <summary>An end-of-line anchor, e.g. `$` in <see cref="RegexOptions.Multiline"/> mode.</summary>
88/// <summary>A word boundary anchor, e.g. `\b` in <see cref="RegexOptions.ECMAScript"/> mode.</summary>
90/// <summary>Not a word boundary anchor, e.g. `\B` in <see cref="RegexOptions.ECMAScript"/> mode..</summary>
92/// <summary>A beginning-of-string anchor, e.g. `\A`, or `^` when not in <see cref="RegexOptions.Multiline"/> mode.</summary>
96/// <summary>A end-of-string-or-before-ending-newline anchor, e.g. `\Z`, or `$` when not in <see cref="RegexOptions.Multiline"/> mode.</summary>
156/// A positive lookaround assertion: lookahead if <see cref="RegexOptions.RightToLeft"/> is not set and lookbehind if
157/// <see cref="RegexOptions.RightToLeft"/> is set, e.g. `(?=abc)` or `(?<=abc)`.</summary>
161/// A negative lookaround assertion: lookahead if <see cref="RegexOptions.RightToLeft"/> is not set and lookbehind if
162/// <see cref="RegexOptions.RightToLeft"/> is set, e.g. `(?!abc)` or `(?<!abc)`.</summary>
src\runtime\src\libraries\System.Text.RegularExpressions\src\System\Text\RegularExpressions\RegexParser.cs (103)
47private RegexOptions _options;
55private RegexParser(string pattern, RegexOptions options, CultureInfo culture, Hashtable caps, int capsize, Hashtable? capnames, Span<int> optionSpan)
85internal static CultureInfo GetTargetCulture(RegexOptions options) =>
87(options & RegexOptions.CultureInvariant) != 0 ? CultureInfo.InvariantCulture : CultureInfo.CurrentCulture;
90public static unsafe RegexOptions ParseOptionsInPattern(string pattern, RegexOptions options)
98parser.CountCaptures(out RegexOptions foundOptionsInPattern);
103public static unsafe RegexTree Parse(string pattern, RegexOptions options, CultureInfo culture)
137public static unsafe RegexReplacement ParseReplacement(string pattern, RegexOptions options, Hashtable caps, int capsize, Hashtable capnames)
140CultureInfo culture = (options & RegexOptions.CultureInvariant) != 0 ? CultureInfo.InvariantCulture : CultureInfo.CurrentCulture;
223var parser = new RegexParser(input, RegexOptions.None, CultureInfo.InvariantCulture, new Hashtable(), 0, null, stackalloc int[OptionStackDefaultSize]);
257private void Reset(RegexOptions options)
277StartGroup(new RegexNode(RegexNodeKind.Capture, (_options & ~RegexOptions.IgnoreCase), 0, -1));
290if ((_options & RegexOptions.IgnorePatternWhitespace) != 0)
346string setString = ScanCharClass((_options & RegexOptions.IgnoreCase) != 0, scanOnly: false)!.ToStringClass();
347_unit = new RegexNode(RegexNodeKind.Set, _options & ~RegexOptions.IgnoreCase, setString);
376_options = (RegexOptions)_optionsStack.Pop();
394if ((_options & (RegexOptions.AnyNewLine | RegexOptions.Multiline)) == (RegexOptions.AnyNewLine | RegexOptions.Multiline))
400_unit = new RegexNode((_options & RegexOptions.Multiline) != 0 ? RegexNodeKind.Bol : RegexNodeKind.Beginning, _options);
405if ((_options & RegexOptions.AnyNewLine) != 0)
407_unit = (_options & RegexOptions.Multiline) != 0 ? AnyNewLineEolNode() : AnyNewLineEndZNode();
411_unit = new RegexNode((_options & RegexOptions.Multiline) != 0 ? RegexNodeKind.Eol : RegexNodeKind.EndZ, _options);
416if ((_options & RegexOptions.Singleline) != 0)
418_unit = new RegexNode(RegexNodeKind.Set, _options & ~RegexOptions.IgnoreCase, RegexCharClass.AnyClass);
420else if ((_options & RegexOptions.AnyNewLine) != 0)
422_unit = new RegexNode(RegexNodeKind.Set, _options & ~RegexOptions.IgnoreCase, RegexCharClass.NotAnyNewLineClass);
426_unit = new RegexNode(RegexNodeKind.Notone, _options & ~RegexOptions.IgnoreCase, '\n');
594if ((_options & RegexOptions.ECMAScript) != 0 && _pattern[_pos] == ']')
614if ((_options & RegexOptions.ECMAScript) != 0 && _pos < _pattern.Length && _pattern[_pos] == ']')
672charClass!.AddDigit((_options & RegexOptions.ECMAScript) != 0, ch == 'D', _pattern, _pos);
684charClass!.AddSpace((_options & RegexOptions.ECMAScript) != 0, ch == 'S');
697charClass!.AddWord((_options & RegexOptions.ECMAScript) != 0, ch == 'W');
826if ((_options & RegexOptions.ExplicitCapture) != 0 || _ignoreNextParen)
858_options &= ~RegexOptions.RightToLeft;
864_options &= ~RegexOptions.RightToLeft;
892_options |= RegexOptions.RightToLeft;
903_options |= RegexOptions.RightToLeft;
1112if ((_options & RegexOptions.IgnorePatternWhitespace) != 0)
1120if ((_options & RegexOptions.IgnorePatternWhitespace) != 0 && _pos < _pattern.Length && _pattern[_pos] == '#')
1166(_options & RegexOptions.AnyNewLine) != 0 ? AnyNewLineEndZNode() : new RegexNode(RegexNodeKind.EndZ, _options);
1171new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.ECMAWordClass : RegexCharClass.WordClass);
1176new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.NotECMAWordClass : RegexCharClass.NotWordClass);
1181new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.ECMASpaceClass : RegexCharClass.SpaceClass);
1186new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.NotECMASpaceClass : RegexCharClass.NotSpaceClass);
1191new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.ECMADigitClass : RegexCharClass.DigitClass);
1196new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.NotECMADigitClass : RegexCharClass.NotDigitClass);
1207cc.AddCategoryFromName(ParseProperty(), ch != 'p', (_options & RegexOptions.IgnoreCase) != 0, _pattern, _pos);
1208if ((_options & RegexOptions.IgnoreCase) != 0)
1213return new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), cc.ToStringClass());
1217if (result != null && result.Kind == RegexNodeKind.Backreference && (result.Options & RegexOptions.IgnoreCase) != 0)
1287if ((_options & RegexOptions.ECMAScript) != 0)
1389if (!angled && (_options & RegexOptions.ECMAScript) != 0)
1518if ((_options & RegexOptions.ECMAScript) != 0 && i >= 0x20)
1622RegexOptions options = (char)(ch | 0x20) switch
1624'i' => RegexOptions.IgnoreCase,
1625'm' => RegexOptions.Multiline,
1626'n' => RegexOptions.ExplicitCapture,
1627's' => RegexOptions.Singleline,
1628'x' => RegexOptions.IgnorePatternWhitespace,
1629_ => RegexOptions.None,
1684if ((_options & RegexOptions.ECMAScript) == 0 && RegexCharClass.IsBoundaryWordChar(ch))
1735RegexOptions lookaheadOpts = _options & ~RegexOptions.RightToLeft;
1736RegexOptions lookbehindOpts = _options | RegexOptions.RightToLeft;
1737RegexOptions lookaheadOptsNoCase = lookaheadOpts & ~RegexOptions.IgnoreCase;
1738RegexOptions lookbehindOptsNoCase = lookbehindOpts & ~RegexOptions.IgnoreCase;
1764RegexOptions opts = _options;
1765RegexOptions lookaheadOpts = opts & ~RegexOptions.RightToLeft;
1766RegexOptions lookaheadOptsNoCase = lookaheadOpts & ~RegexOptions.IgnoreCase;
1801RegexOptions opts = _options;
1802RegexOptions lookaheadOpts = opts & ~RegexOptions.RightToLeft;
1803RegexOptions lookaheadOptsNoCase = lookaheadOpts & ~RegexOptions.IgnoreCase;
1827RegexOptions opts = _options;
1828RegexOptions lookbehindOpts = opts | RegexOptions.RightToLeft;
1829RegexOptions lookbehindOptsNoCase = lookbehindOpts & ~RegexOptions.IgnoreCase;
1850'b' => (_options & RegexOptions.ECMAScript) != 0 ? RegexNodeKind.ECMABoundary : RegexNodeKind.Boundary,
1851'B' => (_options & RegexOptions.ECMAScript) != 0 ? RegexNodeKind.NonECMABoundary : RegexNodeKind.NonBoundary,
1862private void CountCaptures(out RegexOptions optionsFoundInPattern)
1865optionsFoundInPattern = RegexOptions.None;
1882if ((_options & RegexOptions.IgnorePatternWhitespace) != 0)
1896_options = (RegexOptions)_optionsStack.Pop();
1967if ((_options & RegexOptions.ExplicitCapture) == 0 && !_ignoreNextParen)
2194_concatenation!.AddChild(RegexNode.CreateOneWithCaseConversion(_pattern[pos], isReplacement ? _options & ~RegexOptions.IgnoreCase : _options, _culture, ref _caseBehavior));
2197case > 1 when (_options & RegexOptions.IgnoreCase) == 0 || isReplacement || !RegexCharClass.ParticipatesInCaseConversion(_pattern.AsSpan(pos, cch)):
2198_concatenation!.AddChild(new RegexNode(RegexNodeKind.Multi, _options & ~RegexOptions.IgnoreCase, _pattern.Substring(pos, cch)));