Lukas Lukac
Lukas Lukac

Reputation: 8346

Stucked at one regular expression

I am trying to match everything (backward) from "*" ...baaack... and immediately when first ")" will be find stop.

Example:

teeeext)
text))))
from next line start selecting because this is last ")")

SELECT
SELECT
SELECT
*** // stop selecting 

I came with this expression:

(?<=\)).+\*

But this selects everything from first ")" until *

Upvotes: 1

Views: 81

Answers (4)

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76395

Let me see if I understand this question properly. You want to match everything that follows the last closing parentheses ()), and preceeds ***.
The expression you're looking for, I think is this:

preg_match('/(?<=\))[^)]+(?=\*{3})/m',$text, $matches);

Which, when applied to your example string returns:

array (
    0 => '

      SELECT
      SELECT
      SELECT
      ',
)

How it works:

  • (?<=\)): a positive lookbehind. The rest of the expression can only match, if it was preceeded by )
  • [^)]+: Matches everything but ), this is to make sure the lookbehind references the last closing )
    There's no need for you to include * in the non-matching chars. If the delimiter is three asterisk chars, even so, if to be sure, you can make this pattern non-greedy: [^\)]+?. If the end-delimiter might be a single asterisk, you should include the * in this class ([)*]+).
  • (?=\*{3}): positive lookahead. The preceding ([\)]+) can only be matched provided it is followed by ***
    If a single * is enough to delimit the section you wish to match, change the regex to /(?=\))[^)]+(?=\*)/.
  • m: the multi-line modifier, because your example is a multiline string, it could come in useful

The matches of the lookaround assertions are zero-width, and will not be part of the match. Job done.
The main "trick" is that the chars that you have to use in your lookarounds are special chars in a regular expression, and need to be escaped, hence \* and \) instead of just simple * and )

Upvotes: 1

blackSmith
blackSmith

Reputation: 3154

You can try something like :

[^)*]+(?=\*)

Meaning : greedily take every non-')' and non-'*' character until a * is encountered.

Upvotes: 0

p.s.w.g
p.s.w.g

Reputation: 149020

If you want to match everything from the last ) character to the first * character use this pattern:

(?<=\))[^)*]+\*

The [^)*] means any character except ) or *. But this will include the first * in the match. If you'd like to have it not to include the *, use a look-ahead:

(?<=\))[^)*]+(?=\*)

Alternatively, if you are willing to make a bit of change to your code, you can just use a group:

\)([^)*]+)\*

But you'll have to do a little more work to extract this group from the match.

Upvotes: 3

Itay
Itay

Reputation: 16777

\)([^(\))])*$

This one works for me.

Upvotes: 0

Related Questions