Home > database >  Regex for find value between curly braces which have pipe separator
Regex for find value between curly braces which have pipe separator

Time:12-08

$str = ({max_w} * {max_h} * {key|value}) / {key_1|value}

I have the above formula, I want to match the value with curly braces and which has a pipe separator. Right now the issue is it's giving me the values which have not pipe separator. I am new in regex so not have much idea about that. I tried below one

preg_match_all("^\{(|.*?|)\}^",$str, PREG_PATTERN_ORDER);

It gives below output

Array
(
    [0] => key|value
    [1] => max_w
    [2] => max_h
    [3] => key_1|value
)

Expected output

Array
(
    [0] => key|value
    [1] => key_1|value
)

CodePudding user response:

Not sure about PHP. Here's the general regex that will do this.

{([^{}]*\|[^{}]*)}

Here is the demo.

CodePudding user response:

You can use

(?<={)[^}]*\|[^}]*(?=})

For the given string the two matches are shown by the pointy characters:

({max_w} * {max_h} * {key|value}) / {key_1|value}
                      ^^^^^^^^^      ^^^^^^^^^^^ 

Demo

(?<={) is a positive lookbehind. Arguably, the positive lookahead (?=}) is not be needed if it is known that all braces appear in matching, non-overlapping pairs.

CodePudding user response:

The pattern \{(|.*?|)\} has 2 alternations | that can be omitted as the alternatives on the left and right of it are not really useful.

That leaves \{(.*?)} where the . can match any char including a pipe char, and therefore does not make sure that it is matched in between.

You can use a pattern that does not crosses matching a curly or a pipe char to match a single pipe in between.

{\K[^{}|]*\|[^{}|]*(?=})
  • { Match opening {
  • \K Forget what is matches until now
  • [^{}|]* Match any char except the listed
  • \| Match a | char
  • [^{}|]* Match any char except the listed
  • (?=}) Assert a closing } to the right

Regex demo | PHP demo

$str = "({max_w} * {max_h} * {key|value}) / {key_1|value}";
$pattern = "/{\K[^{}|]*\|[^{}|]*(?=})/";
preg_match_all($pattern, $str, $matches);
print_r($matches[0]);

Output

Array
(
    [0] => key|value
    [1] => key_1|value
)

Or using a capture group:

{([^{}|]*\|[^{}|]*)}

Regex demo

  • Related