no_lyf_programmer
no_lyf_programmer

Reputation: 595

Recursive regex for closed parenthesis

I'm trying to write a regular expression in ruby to a pattern which should matches to following criteria

/{{\d+}}/ double curly braces,with a number inside the it

/.*{{\d+}}.*/ it can be preceded or followed by any number of characters

/.*{{\d+}}.*\m/ it can be multi lines

till this part it is working

it accepting strings like "afaf{{}}{{" , So I made changes as

/(?:(.*\{\{\d+\}\}.*)\g<1>\m)/ can have multiple *{{number}}*

eg.

empty string

xyz

{{345345}}

any thing{{234234324}}

<abc>{{234234}}<-

any chars{{234}}
{{234234}}any chars
{{4}}

not valid ones

{{non intgers}}

{{5345345}}{{

}}3345345{{

{345345}

{{34534}
}

4545

{234234

{{
5345
}}

but it's not working as expected.

Upvotes: 0

Views: 115

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626853

You do not seem to need a recursion here, just use grouping constructs and negated character classes to make sure you do not match disallowed chars:

rx = /\A(?:[^\d{}]*{{\d+}})*[^\d{}]*\z/

Details

  • \A - start of string
  • (?:[^\d{}]*{{\d+}})* - zero or more sequences of:
    • [^\d{}]* - any 0 or more chars other than digits, { and }
    • {{\d+}} - {{, 1+ digits, }}
  • [^\d{}]* - any 0 or more chars other than digits, { and }
  • \z - end of string.

See the Ruby demo test:

rx = /\A(?:[^\d{}]*{{\d+}})*[^\d{}]*\z/
ss = ['', 'xyz', '{{345345}}','any thing{{234234324}}','<abc>{{234234}}<-',"any chars{{234}}\n{{234234}}any chars\n{{4}}\n" ]
puts "Valid:"
for s in ss
    puts "#{s} => #{(s =~ rx) != nil}"
end

nonss = ['{{non intgers}}','{{5345345}}{{','}}3345345{{','{345345}',"{{34534}\n}", '4545', '{234234', "{{\n5345\n}}" ]
puts "Invalid:"
for s in nonss
    puts "#{s} => #{(s =~ rx) != nil}"
end

Output:

Valid:
 => true
xyz => true
{{345345}} => true
any thing{{234234324}} => true
<abc>{{234234}}<- => true
any chars{{234}}
{{234234}}any chars
{{4}}
 => true
Invalid:
{{non intgers}} => false
{{5345345}}{{ => false
}}3345345{{ => false
{345345} => false
{{34534}
} => false
4545 => false
{234234 => false
{{
5345
}} => false

Upvotes: 1

leoinstack
leoinstack

Reputation: 26

Try with this:

(?m)^(?:(?:.+)?(?:{{)(?<NUM>\d+)(?:}})(?:.+)?)$

Test at https://regex101.com/r/WIuDhw/1/

Upvotes: 0

Related Questions