Brad
Brad

Reputation: 12272

How to account for two different types of strings when using preg_match?

I need help modifying the regex that is being used as the pattern in preg_match to account for both types of strings, one with the last name, and one without the last name.

$string = "Tim Johnson (M) - 12/19/2001 (14 years)";

$re = '~^(?<fname>[\p{L}-]+)\h+(?<lname>[\p{L}\h-]+?)\h+\((?<gender>[MF])\)[-\h]+(?<dob>[\d/]+)~mu';

preg_match($re, $string, $matches);

will return an array of:

array(
  'fname'  => 'Tim',
  'lname'  => 'Johnson',
  'gender' => 'M',
  'dob'    => '12/29/2001',
)

But if the string is (missing the last name):

$string = "Tim (M) - 12/19/2001 (14 years)";

It will return an array of:

array(
  'fname'  => '',
  'lname'  => '',
  'gender' => 'M',
  'dob'    => '',
)

Upvotes: 2

Views: 67

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627292

Use an optional non-capturing group around \h+(?<lname>[\p{L}\h-]+?) pattern:

^(?<fname>[\p{L}-]+)(?:\h+(?<lname>[\p{L}\h-]+?))?\h+\((?<gender>[MF])\)[-\h]+(?<dob>[\d/]+)
                    ^^^                         ^^

See the regex demo

The (?:...)? is a non-capturing group that has a ? quantifier applied to it, it makes the sequence of patterns inside it match 1 or 0 times, i.e. makes them optional as a sequence.

Upvotes: 2

Related Questions