Gracie williams
Gracie williams

Reputation: 1145

Regex match from right to left

I wanted to match something from right to left, below is one of such example.

100abababab3x3x3xx1000morewords

If i want to match something between and last xx and immediate previous ab and get 3x3x3

I tried something like below , but it matches ababab3x3x3

preg_match('/ab(.*?)xx/',$text,$totmat);

Note : please don't recommend strrev.

Above example is just for illustration , all i wanted to do is match from right to left.

Upvotes: 1

Views: 4077

Answers (3)

A l w a y s S u n n y
A l w a y s S u n n y

Reputation: 38502

Not sure this is the most optimized way or not? But this will work for you if you use the combination of Look ahead positive (?=) and Look behind positive (?<=). See regex

<?php

$re = '/\w+(?<=ab)(.*?)(?=xx)/m';
$str = '100abababab3x3x3xx1000morewords';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

// Print the full matched result
echo $matches[0][1];

DEMO: https://3v4l.org/db69N

Upvotes: 1

Lou
Lou

Reputation: 876

There are other approaches than a regex to this kind of problem that would be close to twice faster in computing time.

Here for example :

$str = "100abababab3x3x3xx1000morewords";
$result = explode("ab", explode("xx", $str)[0]);
var_dump(end($result));

First occurence of explode split the string in two between the "xx" characters. We're only interested by the left part (Index 0).

Second occurence of explode split the string with the caracters ab. We're only interested by the last occurence of ab. Therefore var_dump(end($result)); prints the expected result.

Upvotes: 0

Toto
Toto

Reputation: 91428

$str = '100abababab3x3x3xx1000morewords';
preg_match('/ab((?:(?!ab).)*)xx/', $str, $m);
print_r($m);

Output:

Array
(
    [0] => ab3x3x3xx
    [1] => 3x3x3
)

>Explanation:

ab              : literally ab
  (             : start group 1
    (?:         : start non capture group
      (?!ab)    : negative lookahead, make sure we doon't have ab
      .         : any character but newline
    )*          : end group, may appear 0 or more times
  )             : end group 1
xx              : literally xx

Upvotes: 0

Related Questions