private void ClassifyWholeNode(RegexNode node, string typeName) { foreach (var child in node) { if (child.IsNode) { ClassifyWholeNode(child.Node, typeName); } else { AddClassification(child.Token, typeName); } } }
private Automaton <S> ConvertNodeNotoneloop(RegexNode node) { bool ignoreCase = ((node._options & RegexOptions.IgnoreCase) != 0); S cond = solver.MkNot(solver.MkCharConstraint(node._ch, ignoreCase)); if (!description.ContainsKey(cond)) { description[cond] = string.Format("[^{0}]", Rex.RexEngine.Escape(node._ch)); } Automaton <S> loop = automBuilder.MkOneLoop(cond, node._m, node._n); return(loop); }
private void ProvideBackslashCompletions( EmbeddedCompletionContext context, bool inCharacterClass, RegexNode parentOpt) { if (parentOpt != null && !(parentOpt is RegexEscapeNode)) { return; } if (!inCharacterClass) { context.AddIfMissing(@"\A", Regex_start_of_string_only_short, Regex_start_of_string_only_long, parentOpt); context.AddIfMissing(@"\b", Regex_word_boundary_short, Regex_word_boundary_long, parentOpt); context.AddIfMissing(@"\B", Regex_non_word_boundary_short, Regex_non_word_boundary_long, parentOpt); context.AddIfMissing(@"\G", Regex_contiguous_matches_short, Regex_contiguous_matches_long, parentOpt); context.AddIfMissing(@"\z", Regex_end_of_string_only_short, Regex_end_of_string_only_long, parentOpt); context.AddIfMissing(@"\Z", Regex_end_of_string_or_before_ending_newline_short, Regex_end_of_string_or_before_ending_newline_long, parentOpt); context.AddIfMissing($@"\k< {Regex_name_or_number} >", Regex_named_backreference_short, Regex_named_backreference_long, parentOpt, @"\k<".Length, insertionText: @"\k<>"); // Note: we intentionally do not add `\<>` to the list. While supported by the // .NET regex engine, it is effectively deprecated and discouraged from use. // Instead, it is recommended that `\k<>` is used instead. // // context.AddIfMissing(@"\<>", "", "", parentOpt, @"\<".Length)); context.AddIfMissing(@"\1-9", Regex_numbered_backreference_short, Regex_numbered_backreference_long, parentOpt, @"\".Length, @"\"); } context.AddIfMissing(@"\a", Regex_bell_character_short, Regex_bell_character_long, parentOpt); context.AddIfMissing(@"\b", Regex_backspace_character_short, Regex_backspace_character_long, parentOpt); context.AddIfMissing(@"\e", Regex_escape_character_short, Regex_escape_character_long, parentOpt); context.AddIfMissing(@"\f", Regex_form_feed_character_short, Regex_form_feed_character_long, parentOpt); context.AddIfMissing(@"\n", Regex_new_line_character_short, Regex_new_line_character_long, parentOpt); context.AddIfMissing(@"\r", Regex_carriage_return_character_short, Regex_carriage_return_character_long, parentOpt); context.AddIfMissing(@"\t", Regex_tab_character_short, Regex_tab_character_long, parentOpt); context.AddIfMissing(@"\v", Regex_vertical_tab_character_short, Regex_vertical_tab_character_long, parentOpt); context.AddIfMissing(@"\x##", Regex_hexadecimal_escape_short, Regex_hexadecimal_escape_long, parentOpt, @"\x".Length, @"\x"); context.AddIfMissing(@"\u####", Regex_unicode_escape_short, Regex_unicode_escape_long, parentOpt, @"\u".Length, @"\u"); context.AddIfMissing(@"\cX", Regex_control_character_short, Regex_control_character_long, parentOpt, @"\c".Length, @"\c"); context.AddIfMissing(@"\d", Regex_decimal_digit_character_short, Regex_decimal_digit_character_long, parentOpt); context.AddIfMissing(@"\D", Regex_non_digit_character_short, Regex_non_digit_character_long, parentOpt); context.AddIfMissing(@"\p{...}", Regex_unicode_category_short, Regex_unicode_category_long, parentOpt, @"\p".Length, @"\p"); context.AddIfMissing(@"\P{...}", Regex_negative_unicode_category_short, Regex_negative_unicode_category_long, parentOpt, @"\P".Length, @"\P"); context.AddIfMissing(@"\s", Regex_white_space_character_short, Regex_white_space_character_long, parentOpt); context.AddIfMissing(@"\S", Regex_non_white_space_character_short, Regex_non_white_space_character_long, parentOpt); context.AddIfMissing(@"\w", Regex_word_character_short, Regex_word_character_long, parentOpt); context.AddIfMissing(@"\W", Regex_non_word_character_short, Regex_non_word_character_long, parentOpt); }
private SymbolicRegex <S> ConvertNodeSetToSymbolicRegex(RegexNode node) { //ranges and categories are encoded in set string set = node._str; S moveCond = CreateConditionFromSet((node._options & RegexOptions.IgnoreCase) != 0, set); if (!description.ContainsKey(moveCond)) { description[moveCond] = RegexCharClass.SetDescription(set); } return(this.srBuilder.MkSingleton(moveCond)); }
internal static ParseStep CaptureDiscarded(RegexNode node, string capturedText, int captureNumber) { return(new ParseStep { Type = ParseStepType.CaptureDiscarded, Node = node, MatchedText = capturedText, CaptureNumber = captureNumber }.WithMessage(step => string.Format( "Discarded captured text, '{0}' (capture number: {1})", step.MatchedText, step.CaptureNumber))); }
public void LoopsReducedWithAutoAtomic() { (RegexTree tree, AnalysisResults analysis) = Analyze("a*(b*)c*"); RegexNode rootCapture = AssertNode(analysis, tree.Root, RegexNodeKind.Capture, atomicByAncestor: true, backtracks: false, captures: true, inLoop: false); RegexNode concat = AssertNode(analysis, rootCapture.Child(0), RegexNodeKind.Concatenate, atomicByAncestor: true, backtracks: false, captures: true, inLoop: false); RegexNode aStar = AssertNode(analysis, concat.Child(0), RegexNodeKind.Oneloopatomic, atomicByAncestor: false, backtracks: false, captures: false, inLoop: false); RegexNode implicitBumpalong = AssertNode(analysis, concat.Child(1), RegexNodeKind.UpdateBumpalong, atomicByAncestor: false, backtracks: false, captures: false, inLoop: false); RegexNode bStarCapture = AssertNode(analysis, concat.Child(2), RegexNodeKind.Capture, atomicByAncestor: false, backtracks: false, captures: true, inLoop: false); RegexNode cStar = AssertNode(analysis, concat.Child(3), RegexNodeKind.Oneloopatomic, atomicByAncestor: true, backtracks: false, captures: false, inLoop: false); RegexNode bStar = AssertNode(analysis, bStarCapture.Child(0), RegexNodeKind.Oneloopatomic, atomicByAncestor: false, backtracks: false, captures: false, inLoop: false); }
public void RemoveNodeShouldNotAddEmptyNodeWithIfOldNodeHasNoPrefix() { // Arrange var oldNode = new TestRegexNode(); var target = new ConcatenationNode(new List <RegexNode> { oldNode }); // Act RegexNode result = target.RemoveNode(oldNode); // Assert result.ChildNodes.ShouldBeEmpty(); }
private RegexMutation CharacterClassNegation(CharacterClassNode node, RegexNode root) { var span = node.GetSpan(); var replacementNode = node.Subtraction == null ? new CharacterClassNode(node.CharacterSet, !node.Negated) : new CharacterClassNode(node.CharacterSet, node.Subtraction, !node.Negated); return(new RegexMutation { OriginalNode = node, ReplacementNode = replacementNode, DisplayName = "Regex character class negation mutation", Description = $"Character class \"{node}\" was replaced with \"{replacementNode}\" at offset {span.Start}.", ReplacementPattern = root.ReplaceNode(node, replacementNode).ToString() }); }
/* * Resets parsing to the beginning of the pattern. */ private void Reset(RegexOptions topopts) { _currentPos = 0; _autocap = 1; _ignoreNextParen = false; if (_optionsStack.Count > 0) { _optionsStack.RemoveRange(0, _optionsStack.Count - 1); } _options = topopts; _stack = null; }
/// <summary>Converts the root <see cref="RegexNode"/> into its corresponding <see cref="SymbolicRegexNode{S}"/>.</summary> /// <param name="root">The root node to convert.</param> /// <returns>The generated <see cref="SymbolicRegexNode{S}"/> that corresponds to the supplied <paramref name="root"/>.</returns> internal SymbolicRegexNode <BDD> ConvertToSymbolicRegexNode(RegexNode root) { Debug.Assert(_builder is not null); // Create the root list that will store the built-up result. DoublyLinkedList <SymbolicRegexNode <BDD> > rootResult = new(); // Create a stack to be processed in order to process iteratively rather than recursively, and push the root on. Stack <(RegexNode Node, DoublyLinkedList <SymbolicRegexNode <BDD> > Result, DoublyLinkedList <SymbolicRegexNode <BDD> >[]? ChildResults)> stack = new(); stack.Push((root, rootResult, CreateChildResultArray(root.ChildCount()))); // Continue to iterate until the stack is empty, popping the next item on each iteration. // Some popped items may be pushed back on as part of processing. while (stack.TryPop(out (RegexNode Node, DoublyLinkedList <SymbolicRegexNode <BDD> > Result, DoublyLinkedList <SymbolicRegexNode <BDD> >[]? ChildResults)popped))
public void TestRegexNodeAdditionOperator3() { RegexNodeLiteral literal1 = new RegexNodeLiteral("\\w*"); RegexNodeLiteral literal2 = new RegexNodeLiteral("\\d+"); RegexNodeConcatenation concatenation = new RegexNodeConcatenation(literal1, literal2); RegexNodeLiteral literal3 = new RegexNodeLiteral("\\s?"); RegexNode sum = literal3 + concatenation; Assert.IsInstanceOfType(sum, typeof(RegexNodeConcatenation)); Assert.AreNotSame(concatenation, sum); Assert.AreEqual(literal3, ((RegexNodeConcatenation)sum).ChildNodes[0]); Assert.AreEqual(literal1, ((RegexNodeConcatenation)sum).ChildNodes[1]); Assert.AreEqual(literal2, ((RegexNodeConcatenation)sum).ChildNodes[2]); }
public void AddNodeShouldCopyNodeAndAddNewRegexNode() { // Arrange var target = new TestRegexNode(new List <RegexNode> { new CharacterNode('a'), new CharacterNode('b') }); var newNode = new CharacterNode('c'); // Act RegexNode result = target.AddNode(newNode); // Assert result.ChildNodes.Count().ShouldBe(3); result.ChildNodes.Last().ShouldBe(newNode); }
public void AddNodeShouldCopyPrefix() { // Arrange var prefix = new CommentGroupNode("This is a prefix."); var target = new TestRegexNode { Prefix = prefix }; var newNode = new TestRegexNode(); // Act RegexNode result = target.AddNode(newNode); // Assert result.Prefix.ToString().ShouldBe(target.Prefix.ToString()); }
private void ProvideOpenBracketCompletions( EmbeddedCompletionContext context, bool inCharacterClass, RegexNode parentOpt) { if (inCharacterClass) { // Open bracket doesn't complete to anything inside a character class. return; } context.AddIfMissing($"[ {Regex_character_group} ]", Regex_positive_character_group_short, Regex_positive_character_group_long, parentOpt, positionOffset: "[".Length, insertionText: "[]"); context.AddIfMissing($"[ firstCharacter-lastCharacter ]", Regex_positive_character_range_short, Regex_positive_character_range_long, parentOpt, positionOffset: "[".Length, insertionText: "[-]"); context.AddIfMissing($"[^ {Regex_character_group} ]", Regex_negative_character_group_short, Regex_negative_character_group_long, parentOpt, positionOffset: "[^".Length, insertionText: "[^]"); context.AddIfMissing($"[^ firstCharacter-lastCharacter ]", Regex_negative_character_group_short, Regex_negative_character_range_long, parentOpt, positionOffset: "[^".Length, insertionText: "[^-]"); context.AddIfMissing($"[ {Regex_base_group} -[ {Regex_excluded_group} ] ]", Regex_character_class_subtraction_short, Regex_character_class_subtraction_long, parentOpt, positionOffset: "[".Length, insertionText: "[-[]]"); }
private SymbolicRegexNode <S> ConvertNodeOneloopToSymbolicRegex(RegexNode node, bool isLazy) { bool ignoreCase = ((node._options & RegexOptions.IgnoreCase) != 0); S cond = solver.MkCharConstraint(node._ch, ignoreCase); if (!description.ContainsKey(cond)) { description[cond] = string.Format("{0}", Rex.RexEngine.Escape(node._ch)); } SymbolicRegexNode <S> body = this.srBuilder.MkSingleton(cond); SymbolicRegexNode <S> loop = this.srBuilder.MkLoop(body, isLazy, node._m, node._n); return(loop); }
public void AddNodeResultShouldNotHaveReferenceToOriginalPrefix() { // Arrange var prefix = new CommentGroupNode("This is a prefix."); var target = new TestRegexNode { Prefix = prefix }; var newNode = new TestRegexNode(); // Act RegexNode result = target.AddNode(newNode); // Assert result.Prefix.ShouldNotBe(target.Prefix); }
private static void AddClassifications(RegexNode node, Visitor visitor, EmbeddedLanguageClassificationContext context) { node.Accept(visitor); foreach (var child in node) { if (child.IsNode) { AddClassifications(child.Node, visitor, context); } else { AddTriviaClassifications(child.Token, context); } } }
public void CompositeAddNestedNodeTest() { // Arrange var regexGenerator = new RegexGenerator(); var node1 = new RegexNode(@"[abc]"); var nested1 = new RegexGroupNode(node1, capturing: false, min: 1, max: null, quantifierOption: RegexQuantifierOption.Lazy); var node2 = new RegexConditionalNode(@"a", "b", "c"); var nested2 = new RegexGroupNode(node2, capturing: true, name: "a"); // Act regexGenerator.AddNegativeLookbehindAssertion(nested1) .AddGroup(nested2); // Assert Assert.Equal(@"(?<!(?:[abc])+?)(?<a>(?(?=a)b|c))", regexGenerator.ToString()); }
private static void AddClassifications(RegexNode node, Visitor visitor, ArrayBuilder <ClassifiedSpan> result) { node.Accept(visitor); foreach (var child in node) { if (child.IsNode) { AddClassifications(child.Node, visitor, result); } else { AddTriviaClassifications(child.Token, result); } } }
public string Dump() { var sb = new StringBuilder(); RegexNode node = this; for (var i = 0; node != null; i++) { node = FindNodeById(i); if (node != null) { sb.AppendLine(node.ToString()); } } return(sb.ToString()); }
internal static ParseStep Capture(RegexNode node, string capturedText, int captureNumber, State initialState, State currentState) { return(new ParseStep { Type = ParseStepType.Capture, Node = node, MatchedText = capturedText, CaptureNumber = captureNumber, InitialState = initialState, CurrentState = currentState }.WithMessage(step => string.Format( "Captured '{0}' (capture number: {1}) starting at index {2}", step.MatchedText, step.CaptureNumber, step.InitialState.Index))); }
private SymbolicRegexNode <S> ConvertNodeSetloopToSymbolicRegex(RegexNode node, bool isLazy) { //ranges and categories are encoded in set string set = node._str; S moveCond = CreateConditionFromSet((node._options & RegexOptions.IgnoreCase) != 0, set); if (!description.ContainsKey(moveCond)) { description[moveCond] = RegexCharClass.SetDescription(set); } SymbolicRegexNode <S> body = this.srBuilder.MkSingleton(moveCond); SymbolicRegexNode <S> loop = this.srBuilder.MkLoop(body, isLazy, node._m, node._n); return(loop); }
public void AtomicGroupAroundBacktracking() { (RegexTree tree, AnalysisResults analysis) = Analyze("[ab]*(?>[bc]*[cd])[ef]"); RegexNode rootCapture = AssertNode(analysis, tree.Root, RegexNodeKind.Capture, atomicByAncestor: true, backtracks: true, captures: true, inLoop: false); RegexNode rootConcat = AssertNode(analysis, rootCapture.Child(0), RegexNodeKind.Concatenate, atomicByAncestor: true, backtracks: true, captures: false, inLoop: false); RegexNode abStar = AssertNode(analysis, rootConcat.Child(0), RegexNodeKind.Setloop, atomicByAncestor: false, backtracks: true, captures: false, inLoop: false); RegexNode implicitBumpalong = AssertNode(analysis, rootConcat.Child(1), RegexNodeKind.UpdateBumpalong, atomicByAncestor: false, backtracks: false, captures: false, inLoop: false); RegexNode atomic = AssertNode(analysis, rootConcat.Child(2), RegexNodeKind.Atomic, atomicByAncestor: false, backtracks: false, captures: false, inLoop: false); RegexNode ef = AssertNode(analysis, rootConcat.Child(3), RegexNodeKind.Set, atomicByAncestor: true, backtracks: false, captures: false, inLoop: false); RegexNode atomicConcat = AssertNode(analysis, atomic.Child(0), RegexNodeKind.Concatenate, atomicByAncestor: true, backtracks: true, captures: false, inLoop: false); RegexNode bcStar = AssertNode(analysis, atomicConcat.Child(0), RegexNodeKind.Setloop, atomicByAncestor: false, backtracks: true, captures: false, inLoop: false); RegexNode cd = AssertNode(analysis, atomicConcat.Child(1), RegexNodeKind.Set, atomicByAncestor: true, backtracks: false, captures: false, inLoop: false); }
internal Tuple <string, Automaton <S> >[] ConvertCaptures(RegexNode node, Func <int, string> getCaptureName) { if (node._type == RegexNode.Capture)//single capture { return new Tuple <string, Automaton <S> >[] { new Tuple <string, Automaton <S> >(getCaptureName(node._m), ConvertNode(node)) } } ; if (node._type != RegexNode.Concatenate) { return new Tuple <string, Automaton <S> >[] { new Tuple <string, Automaton <S> >("", ConvertNode(node)) } } ; List <Tuple <string, Automaton <S> > > res = new List <Tuple <string, Automaton <S> > >(); List <RegexNode> between_captures = new List <RegexNode>(); foreach (var n in node._children) { if (n._type != RegexNode.Capture) { between_captures.Add(n); } else { if (between_captures.Count > 0) { var aut = this.automBuilder.MkConcatenate(between_captures.ToArray()); res.Add(new Tuple <string, Automaton <S> >("", aut)); between_captures.Clear(); } var capture = ConvertNode(n); string capture_name = getCaptureName(n._m); res.Add(new Tuple <string, Automaton <S> >(capture_name, capture)); } } if (between_captures.Count > 0) { var aut = this.automBuilder.MkConcatenate(between_captures.ToArray()); res.Add(new Tuple <string, Automaton <S> >("", aut)); between_captures.Clear(); } return(res.ToArray()); }
public void ReplaceNodeShouldCopyNodeAndReplaceOldNodeWithNewNode() { // Arrange var charNodeA = new CharacterNode('a'); var charNodeB = new CharacterNode('b'); var childNodes = new List <RegexNode> { charNodeA, charNodeB }; var target = new TestRegexNode(childNodes); var newNode = new CharacterNode('c'); // Act RegexNode result = target.ReplaceNode(charNodeA, newNode); // Assert result.ChildNodes.Count().ShouldBe(2); result.ChildNodes.First().ShouldBe(newNode); }
public void RemoveNodeShouldHaveNoReferencesToTheOriginalTreeNodes() { // Arrange var charNodeA = new CharacterNode('a'); var charNodeB = new CharacterNode('b'); var childNodes = new List <RegexNode> { charNodeA, charNodeB }; var target = new TestRegexNode(childNodes); // Act RegexNode result = target.RemoveNode(charNodeA); // Assert result.ShouldNotBe(target); result.ChildNodes.ShouldNotContain(charNodeA); result.ChildNodes.ShouldNotContain(charNodeB); }
public void RemoveNodeShouldCopyNodeAndRemoveOldNode() { // Arrange var charNodeA = new CharacterNode('a'); var charNodeB = new CharacterNode('b'); var childNodes = new List <RegexNode> { charNodeA, charNodeB }; var target = new TestRegexNode(childNodes); // Act RegexNode result = target.RemoveNode(charNodeA); // Assert var childNode = result.ChildNodes.ShouldHaveSingleItem(); childNode.ToString().ShouldBe("b"); }
private Automaton <S> ConvertNodeSet(RegexNode node) { //ranges and categories are encoded in set string set = node._str; S moveCond = CreateConditionFromSet((node._options & RegexOptions.IgnoreCase) != 0, set); if (moveCond.Equals(solver.False)) { return(this.automBuilder.empty); //the condition is unsatisfiable } if (!description.ContainsKey(moveCond)) { description[moveCond] = RegexCharClass.SetDescription(set); } return(automBuilder.MkSeq(moveCond)); }
public void AddNodeShouldNotReturnRootNodeIfReturnRootIsFalse() { // Arrange var targetChildNodes = new List <RegexNode> { new CharacterNode('a'), new CharacterNode('b') }; var target = new TestRegexNode(targetChildNodes); var targetParent = new TestRegexNode(target); _ = new TestRegexNode(targetParent); var newNode = new CharacterNode('c'); // Act RegexNode result = target.AddNode(newNode, false); // Assert result.ChildNodes.Count().ShouldBe(3); result.ChildNodes.Last().ShouldBe(newNode); }
//loop constructs private void ConvertNodeLoop(RegexNode node) { var child = node._children[0]; int m = node._m; int n = node._n; if (m == 1 && n == 1) //trivial case: r{1,1} = r { ConvertNode(child); } else if (m == 0 && n == 1) //case: ? { Write("(re-option "); ConvertNode(child); Write(")"); } else if (m == 0 && n == int.MaxValue) //case: * { Write("(re-star "); ConvertNode(child); Write(")"); } else if (m == 1 && n == int.MaxValue) //case: + { Write("(re-plus "); ConvertNode(child); Write(")"); } else if (n == int.MaxValue) //case {m,} { Write(string.Format("(re-concat ((_ re-loop {0} {0}) ", m)); ConvertNode(child); Write(") (re-star "); ConvertNode(child); Write("))"); } else //general case {m,n} { Write(string.Format("((_ re-loop {0} {1}) ", m, n)); ConvertNode(child); Write(")"); } }
/// <summary> /// Concatenates two nodes. /// </summary> /// <param name="node1">First node.</param> /// <param name="node2">Second node.</param> /// <returns>An instance of RegexNode representing the concatenation of child nodes.</returns> public static RegexNodeConcatenation Concatenate(RegexNode node1, RegexNode node2) { return Concatenate(new[] { node1, node2 }); }
internal WrapperNode(RegexNode child, int index, string pattern) : base(index, pattern) { Child = child; }
/// <summary> /// Concatenates four nodes. /// </summary> /// <param name="node1">First node.</param> /// <param name="node2">Second node.</param> /// <param name="node3">Third node.</param> /// <param name="node4">Fourth node.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode representing the concatenation of child nodes.</returns> public static RegexNodeConcatenation Concatenate(RegexNode node1, RegexNode node2, RegexNode node3, RegexNode node4, RegexQuantifier quantifier) { return Concatenate(new[] { node1, node2, node3, node4 }, quantifier); }
/// <summary> /// Generates an alternation expression with two options ("a|b"). /// </summary> /// <param name="expression1">First option.</param> /// <param name="expression2">Second option.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode containing the alternation expression.</returns> public static RegexNodeAlternation Alternate(RegexNode expression1, RegexNode expression2, RegexQuantifier quantifier) { return new RegexNodeAlternation(expression1, expression2) { Quantifier = quantifier }; }
public GreedyPlus(RegexNode child, int index, string pattern) : base(1, null, child, index, pattern) { }
public PossessiveStar(RegexNode child, int index, string pattern) : base(0, null, child, index, pattern) { }
/// <summary> /// Generates a conditional match expression which uses a named group for condition evaluation ("(?(GroupName)|(true)|(false))"). /// </summary> /// <param name="conditionGroupName">The name of the group to be used as a condition.</param> /// <param name="trueMatchExpression">True match expression.</param> /// <param name="falseMatchExpression">False match expression.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode containing the conditional match expression.</returns> public static RegexNodeConditionalMatch ConditionalMatch(string conditionGroupName, RegexNode trueMatchExpression, RegexNode falseMatchExpression, RegexQuantifier quantifier) { return new RegexNodeConditionalMatch(conditionGroupName, trueMatchExpression, falseMatchExpression) { Quantifier = quantifier }; }
/// <summary> /// Generates a zero-width negative lookahead assertion ("match(?!lookahead)"). /// </summary> /// <param name="lookupExpression">Lookahead expression.</param> /// <param name="matchExpression">Match expression.</param> /// <returns>An instance of RegexNode containing the negative lookahead assertion.</returns> public static RegexNodeLookAround NegativeLookAhead(RegexNode lookupExpression, RegexNode matchExpression) { return new RegexNodeLookAround(RegexLookAround.NegativeLookAhead, lookupExpression, matchExpression); }
/// <summary> /// Generates a zero-width negative lookahead assertion ("match(?!lookahead)"). /// </summary> /// <param name="lookupExpression">Lookahead expression.</param> /// <param name="matchExpression">Match expression.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode containing the negative lookahead assertion.</returns> public static RegexNodeLookAround NegativeLookAhead(RegexNode lookupExpression, RegexNode matchExpression, RegexQuantifier quantifier) { return new RegexNodeLookAround(RegexLookAround.NegativeLookAhead, lookupExpression, matchExpression) { Quantifier = quantifier }; }
/// <summary> /// Generates a non-capturing group with the specified subexpression. /// </summary> /// <param name="matchExpression">Inner expression.</param> /// <returns>An instance of RegexNode containing the non-capturing group.</returns> public static RegexNodeGroup NonCapturingGroup(RegexNode matchExpression) { return new RegexNodeGroup(matchExpression, false); }
/// <summary> /// Generates a non-capturing group with the specified subexpression. /// </summary> /// <param name="matchExpression">Inner expression.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode containing the non-capturing group.</returns> public static RegexNodeGroup NonCapturingGroup(RegexNode matchExpression, RegexQuantifier quantifier) { return new RegexNodeGroup(matchExpression, false) { Quantifier = quantifier }; }
/// <summary> /// Generates a zero-width positive lookbehind assertion ("(?<=lookbehind)match"). /// </summary> /// <param name="lookupExpression">Lookbehind expression.</param> /// <param name="matchExpression">Match expression.</param> /// <returns>An instance of RegexNode containing the positive lookbehind assertion.</returns> public static RegexNodeLookAround PositiveLookBehind(RegexNode lookupExpression, RegexNode matchExpression) { return new RegexNodeLookAround(RegexLookAround.PositiveLookBehind, lookupExpression, matchExpression); }
/// <summary> /// Generates a zero-width positive lookbehind assertion ("(?<=lookbehind)match"). /// </summary> /// <param name="lookupExpression">Lookbehind expression.</param> /// <param name="matchExpression">Match expression.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode containing the positive lookbehind assertion.</returns> public static RegexNodeLookAround PositiveLookBehind(RegexNode lookupExpression, RegexNode matchExpression, RegexQuantifier quantifier) { return new RegexNodeLookAround(RegexLookAround.PositiveLookBehind, lookupExpression, matchExpression) { Quantifier = quantifier }; }
/// <summary> /// Generates a subexpression with disabled backtracking ("(?>expression)"). /// </summary> /// <param name="innerExpression">Inner expression.</param> /// <returns>An instance of RegexNode containing the expression with suppressed backtracking.</returns> public static RegexNodeBacktrackingSuppression BacktrackingSuppression(RegexNode innerExpression) { return new RegexNodeBacktrackingSuppression(innerExpression); }
public LazyQuestionMark(RegexNode child, int index, string pattern) : base(0, 1, child, index, pattern) { }
/// <summary> /// Generates an alternation expression with two or more options ("a|b|c|..."). /// </summary> /// <param name="expressions">Array of option expressions.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode containing the alternation expression.</returns> public static RegexNodeAlternation Alternate(RegexNode[] expressions, RegexQuantifier quantifier) { return new RegexNodeAlternation(expressions) { Quantifier = quantifier }; }
/// <summary> /// Generates a conditional match expression ("(?(condition)|(true)|(false))"). /// </summary> /// <param name="conditionExpression">Condition expression.</param> /// <param name="trueMatchExpression">True match expression.</param> /// <param name="falseMatchExpression">False match expression.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode containing the conditional match expression.</returns> public static RegexNodeConditionalMatch ConditionalMatch(RegexNode conditionExpression, RegexNode trueMatchExpression, RegexNode falseMatchExpression, RegexQuantifier quantifier) { return new RegexNodeConditionalMatch(conditionExpression, trueMatchExpression, falseMatchExpression) { Quantifier = quantifier }; }
public GreedyStar(RegexNode child, int index, string pattern) : base(0, null, child, index, pattern) { }
public PossessivePlus(RegexNode child, int index, string pattern) : base(1, null, child, index, pattern) { }
/// <summary> /// Generates an alternation expression with two or more options ("a|b|c|..."). /// </summary> /// <param name="expressions">Array of option expressions.</param> /// <returns>An instance of RegexNode containing the alternation expression.</returns> public static RegexNodeAlternation Alternate(RegexNode[] expressions) { return new RegexNodeAlternation(expressions); }
/// <summary> /// Generates a conditional match expression ("(?(condition)|(true)|(false))"). /// </summary> /// <param name="conditionExpression">Condition expression.</param> /// <param name="trueMatchExpression">True match expression.</param> /// <param name="falseMatchExpression">False match expression.</param> /// <returns>An instance of RegexNode containing the conditional match expression.</returns> public static RegexNodeConditionalMatch ConditionalMatch(RegexNode conditionExpression, RegexNode trueMatchExpression, RegexNode falseMatchExpression) { return new RegexNodeConditionalMatch(conditionExpression, trueMatchExpression, falseMatchExpression); }
/// <summary> /// Generates a named capturing group with the specified subexpression. /// </summary> /// <param name="groupName">Group name.</param> /// <param name="matchExpression">Inner expression.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode containing the named capturing group.</returns> public static RegexNodeGroup Group(string groupName, RegexNode matchExpression, RegexQuantifier quantifier) { return new RegexNodeGroup(matchExpression, groupName) { Quantifier = quantifier }; }
/// <summary> /// Concatenates an array of nodes. /// </summary> /// <param name="expressions">Nodes to concatenate.</param> /// <returns>An instance of RegexNode representing the concatenation of child nodes.</returns> public static RegexNodeConcatenation Concatenate(RegexNode[] expressions) { return new RegexNodeConcatenation(expressions); }
/// <summary> /// Generates a named capturing group with the specified subexpression. /// </summary> /// <param name="groupName">Group name.</param> /// <param name="matchExpression">Inner expression.</param> /// <returns>An instance of RegexNode containing the named capturing group.</returns> public static RegexNodeGroup Group(string groupName, RegexNode matchExpression) { return new RegexNodeGroup(matchExpression, groupName); }
/// <summary> /// Concatenates four nodes. /// </summary> /// <param name="node1">First node.</param> /// <param name="node2">Second node.</param> /// <param name="node3">Third node.</param> /// <param name="node4">Fourth node.</param> /// <returns>An instance of RegexNode representing the concatenation of child nodes.</returns> public static RegexNodeConcatenation Concatenate(RegexNode node1, RegexNode node2, RegexNode node3, RegexNode node4) { return Concatenate(new[] { node1, node2, node3, node4 }); }
/// <summary> /// Generates an unnamed capturing group with the specified subexpression. /// </summary> /// <param name="matchExpression">Inner expression.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode containing the unnamed capturing group.</returns> public static RegexNodeGroup Group(RegexNode matchExpression, RegexQuantifier quantifier) { return new RegexNodeGroup(matchExpression) { Quantifier = quantifier }; }
public GreedyQuantifier(int min, int? max, RegexNode child, int index, string pattern) : base(min, max, child, index, pattern) { }
/// <summary> /// Generates an unnamed capturing group with the specified subexpression. /// </summary> /// <param name="matchExpression">Inner expression.</param> /// <returns>An instance of RegexNode containing the unnamed capturing group.</returns> public static RegexNodeGroup Group(RegexNode matchExpression) { return new RegexNodeGroup(matchExpression); }
public PossessiveQuantifier(int min, int? max, RegexNode child, int index, string pattern) : base(min, max, child, index, pattern) { }
/// <summary> /// Generates a subexpression with disabled backtracking ("(?>expression)"). /// </summary> /// <param name="innerExpression">Inner expression.</param> /// <param name="quantifier">Node quantifier.</param> /// <returns>An instance of RegexNode containing the expression with suppressed backtracking.</returns> public static RegexNodeBacktrackingSuppression BacktrackingSuppression(RegexNode innerExpression, RegexQuantifier quantifier) { return new RegexNodeBacktrackingSuppression(innerExpression) { Quantifier = quantifier }; }