gurehbgui
gurehbgui

Reputation: 14684

Regex Help (PHP) in finding and selecting characters between 2 strings

i need help with an Reg. Ex. i have a long text with many whitespaces and new lines, i need to find and select ALL between 2 strings. example:

iojge test rgej <foo>
ferfe 098n34hjlrej
fefe <end

i want to find all between test and end:

 rgej <foo>
ferfe 098n34hjlrej
fefe <

how can i do this?

Upvotes: 1

Views: 564

Answers (4)

Gumbo
Gumbo

Reputation: 655189

If you have fixed delimiters, you don’t need regular expressions:

$str = 'iojge test rgej <foo>
ferfe 098n34hjlrej
fefe <end';
$start = 'test';
$end = 'end';
if (($startPos = strpos($str, $start)) !== false && ($endPos = strpos($str, $end, $startPos+=strlen($start))) !== false) {
    // match found
    $match = substr($str, $startPos, $endPos-$startPos);
}

Upvotes: 0

codaddict
codaddict

Reputation: 454960

Alternatively you can also do:

$arr1 = explode("test",$input);
$arr2 = explode("end",$arr1[1]);
$result = $arr2[0];

Upvotes: 1

Daniel Vandersluis
Daniel Vandersluis

Reputation: 94133

You can use two lookarounds and the /s (single line) modifier, which makes the dot match newlines, to look for everything between your two words:

/(?<=test).*(?=end)/s

To explain:

(?<=    # open a positive lookbehind
  test  # match 'test'
)       # close the lookbehind
.*      # match as many characters as possible (including newlines because of the \s modifier)
(?=     # open a positive lookahead
 end    # match 'end'
)       # close the lookahead

The lookarounds will let you assert that the pattern must be anchored by your two words, but since lookarounds are not capturing, only everything between the words will be returned by preg_match. A lookbehind looks behind the current position to see if the assertion passes; a lookahead looks after the current position.

Since regular expressions are greedy by default, the .* will match as much as it can (so if the ending word appears multiple times, it will match until the last one). If you want to match only until the first time it encounters end, you can make the .* lazy (in other words, it'll match as little as possible that still satisfies the pattern) by changing it to .*? (ie. /(?<=test).*?(?=end)/s).

Upvotes: 2

Colin Hebert
Colin Hebert

Reputation: 93157

You can try

preg_match("/test(.*?)end/s", $yourString, $matches);
print_r($matches);

Upvotes: 4

Related Questions