Home > Blockchain >  Capture results between delimiters. Content may contain a delimiter character
Capture results between delimiters. Content may contain a delimiter character

Time:05-19

I have the following reg exp: /@\w (\(((?:(?!\))\S|\s)*)\))?/m

And the value I'm expecting are template files like:

@for($i = 0; $i < 10; $i  )
    {{ $i }}
@endfor

@if(
    !empty($name)
    && $name == 'Carlos'
)
    Hi Carlos
@endif

@csfr

I'm having trouble capturing the full content from @if parenthesis.

The expected result would be:

!empty($name)
&& $name == 'Carlos'

But it returns this instead because of the closing parenthesis from the empty function:

!empty($name

How to capture the full expression, since this could contain calls to other functions?

Regexp debug link: https://regex101.com/r/58ZbXe/1

CodePudding user response:

You can use

@\w (\(((?:[^()]  |(\g<1>))*)\))?

See the regex demo.

Details:

  • @ - a @ char
  • \w - one or more word chars
  • (\(((?:[^()] |(\g<1>))*)\))? - Group 1 (optional):
    • \( - a ( char
    • ((?:[^()] |(\g<1>))*) - Group 2:
      • (?:[^()] |(\g<1>))* - zero or more repetitions of either one or more chars other than ( and ) or Group 1 pattern
    • \) - a ) char.

CodePudding user response:

Try with this regex:

@(?<begin>[A-Za-z] )\((?<content>[^@]*)\)[^@] @(?<end>end\1)

Explanation:

  • @: @
  • (?<begin>[A-Za-z] ): Group 1 (begin tag)
    • [A-Za-z] : any combination of alphabetical character
  • \(: open parenthesis
  • (?<content>[^@]*): Group 2 (content of parenthesis)
    • [^@]*: any character other than @
  • \): closed parenthesis
  • [^@] : any character other than @
  • @: @
  • (?<end>end\1): Group 3 (end tag)
    • @: @
    • end: end
    • \1: content from first group

Try it here.

CodePudding user response:

This is the shortest regex I could think of:

@\w \(((\(.*?\)|.)*?)\)

See live demo.

Use the DOTALL flag and your target is in group 1.

This works by matching either bracketed content or dot within the brackets.


If you need the leading newline trimmed from the @if contents:

@\w \(\n?((\(.*?\)|.)*?)\)

See live demo.

  • Related