regexp/backtracking_engine.rb

tests/_examples/regexp/backtracking_engine.rb in the metorex repository.

# A pattern gives back what it read when a piece further on cannot carry on,
# which is what lets a group's text be matched again later.
p(/(ab)\1/.match("abab")[0])
p(/(?<held>ab)\k<held>/.match("abab")[0])

# Text before the match can be checked without reading it.
p("foobar"[/(?<=foo)bar/])
p("bazbar"[/(?<!foo)bar/])

# A group that gives nothing back once it has matched.
p(/(?>a*)a/.match("aaa"))
p(/a*+a/.match("aaa"))
p(/a*a/.match("aaa")[0])

# The same name may be written on more than one group, and the one that
# matched is the one it stands for.
p(/(?<side>left)|(?<side>right)/.match("right")[:side])

# A group's pattern can be matched again by name.
p(/(?<pair>a)\g<pair>/.match("aa")[0])

# The runs a backslash names cover ASCII, while the bracket names cover every
# character they fit.
p("é" =~ /\w/)
p("é" =~ /[[:alpha:]]/)

# One character as a reader sees it, marks and all.
p(/\X/.match("\u{1F918}\u{1F3FD}")[0])

Output:

"abab"
"abab"
"bar"
"bar"
nil
nil
"aaa"
"right"
"aa"
nil
0
"🤘🏽"