clarkk clarkk - 1 year ago 56
PHP Question

positive look behind match until newline or start of string

I need to match a datestamp and then look behind until start of string or new line


$date_day_pattern = '(?:0[1-9]|[12][0-9]|3[01])';
$date_month_pattern = '(?:0[1-9]|1[0-2])';
$date_year_pattern = '(?:[12][0-9]|20[12][0-9])';

$prefix_pattern = '(?<=[^\n]*)';
$date_pattern = "(?<!\d|\d )($date_day_pattern)[^\d\n]?($date_month_pattern)[^\d\n]?($date_year_pattern)(?!\d)";

preg_match("/$prefix_pattern$date_pattern/", $input, $matches);


dksj dkk
49.. dk /ak 01-05-2012 hey


49.. dk /ak




Answer Source

It is clear that you think adding a lookbehind you can capture the beginning of the line before the date your main $date_pattern matches.

It is not possible to use a lookbehind of unknown width in PCRE regex.

Instead, you may capture all the text from the beginning of the line (^ with the MULTILINE modifier) up to the first date with lazy dot matching.

Here are two line changed that do the trick:

$prefix_pattern = '^(.*?)\s*';
preg_match("/$prefix_pattern$date_pattern/m", $input, $matches);

See the IDEONE demo

This way, the $prefix_pattern is equal to ^(.*?)\s* matching the start of line (as /m is added to the preg_match pattern), 0+ chars other than a newline, as few as possible (.*?), are captured into Group 1, and 0+ whitespaces are matched outside that group with \s*.

You may further tweak group number/boundaries to adjust the resulting array of captured values.