Kristian Rafteseth
Kristian Rafteseth

Reputation: 2032

How to get only one match in this regex?

I'm making a script going through tons of emails looking for two strings.

Either it will find been all shipped on [timestamp here] or shipped by the seller on [timestamp here].

Now I get a empty match on $res[1] if it only finds the second string, and empty in the $res[2] if it only finds the first. How can I fix this so it will always fill $res[1] with the timestamp found?

if (preg_match("/been all shipped on ([0-9]{4}\.[0-9]{2}\.[0-9]{2} [0-9]{2}:[0-9]{2})|shipped by the seller on ([0-9]{4}\.[0-9]{2}\.[0-9]{2} [0-9]{2}:[0-9]{2})/", strip_tags($message), $res)) {

}

Upvotes: 2

Views: 103

Answers (2)

Akshay Kalose
Akshay Kalose

Reputation: 777

You have to isolate the timestamp and put the rest inside an alternation:

"/(?:been all shipped|shipped by the seller) on (\d{4}\.\d{2}\.\d{2} \d{2}:\d{2})/"

Regular expression visualization

Debuggex Demo

Upvotes: 6

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89629

@Akshay2598 has the most appropriate answer for your case.

Another way: you can use the "branch reset" feature:

if (preg_match("/(?|been all shipped on ([0-9]{4}\.[0-9]{2}\.[0-9]{2} [0-9]{2}:[0-9]{2})|shipped by the seller on ([0-9]{4}\.[0-9]{2}\.[0-9]{2} [0-9]{2}:[0-9]{2}))/", strip_tags($message), $res)) {

}

With this feature , the groups have the same number: (?|....(..)....|....(..)....). That can be useful for more complex cases.

Upvotes: 2

Related Questions