Andreas W. Wylach
Andreas W. Wylach

Reputation: 737

Regex Pattern and optional matches

I have a problem with a regex pattern and optional matches. Basically I try to extract info from a string containing working hours, that could be of the 3 following forms:

$d1 = 'Fr: 9-12;';
$d2 = 'Mo: 9-12 und 15-18; alle 14 Tage spez. Migräneberatung bis 20 Uhr;';
$d3 = 'Mo: 9-12; alle 14 Tage spez. Migräneberatung bis 20 Uhr;';

$regex = '
    /
        (Mo|Di|Mi|Do|Fr|Sa|So)+:          # day follow by colon
            \s+?                          # a optional space
        (\d+)\-(\d+)                      # time from - to
        (?:\s+?und\s+?(\d+)\-(\d+))       # optional time from - to
            ;                               
        (?:([^;]+))                       # optional addt info
    /x';

$rc = preg_match_all($regex, $d2, $m);

print_r($m);

The string $d2 is working without problem and I get all expected matches, but the strings $d1 and $d3 do not match. I tried the optional grouping with the 2nd time-part and the additional info text but it does not work. I get empty matches instead. I can not see the flaw ...

I would like to use preg_match_all to get all occurrences of such above sub-string, because it is a large string for each day Monday to Sunday with above sub-strings in form of $d1 - $d3 per day. I do not know if I can also use the semicolon as this sub-string end-marker, this is why I try to match it with ([^;]+). If this is not working I could choose another delimiter that marks the end of one day sub-string and just split the large string first and match the sub-strings in a loop.

I appreciate any hints! Thanks in advance for the help!

Upvotes: 1

Views: 340

Answers (1)

eis
eis

Reputation: 53462

I may be wrong here, but this seems to work:

$regex = '
    /
        (Mo|Di|Mi|Do|Fr|Sa|So):           # day follow by colon
            \s+?                          # a optional space
        (\d+)\-(\d+)                      # time from - to
        (?:\s+?und\s+?(\d+)\-(\d+))?      # optional time from - to
            ;
        (?:([^;]+))?                      # optional addt info
    /x';

Just added the optionality (question marks) for optional elements.

Upvotes: 2

Related Questions