简体   繁体   中英

Making a capturing group optional in a regex

I have an automatically-generated email that I'm trying to parse out into fields for import into an application. I have a working regex for if all of the fields are present. However, this won't always be the case. Specifically, the phone number will sometimes be missing.

$regex = '/Bill\sTo:\s+([A-Za-z]+\s[A-Za-z]+)\s.+[A-Z]{2}\s(\d{5})\s.*\s((?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}(?:\-?|\ ?))[2-9]\d{2}[- ]?\d{4})\s+([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})\s+Ship\sTo:/s';
//                     ^       Name         ^    ^State ^  ^ Zip ^      ^                       Phone Number                            ^   ^                      Email                    ^

if (preg_match($regex, $content, $matches)) {
    $import = new ImportedEmail;

    $import->name = $matches[1];
    $import->zip = $matches[2];
    $import->phone = $matches[3];
    $import->email = $matches[4];

    // ...more processing code follows.
}

How can I get it to extract a phone number when it's present, but drop a NULL into $import->phone otherwise?

Note that "State" is in the regex just to help zero in on the location of the zip code.

You can give the capture group a name (?P<name> ...) and make it optional using the ? .

I have prepared a simplified example. Let's say you have a string like:

name [age (optional)] message:

You can parse it with the following regex:

// Jon is 37 years old 
$str1 = 'jon 37 hello world';
// Jane does not tell about her age ;)
$str2 = 'jane foo bar';

preg_match('/(?P<name>[a-z]+ )?(?P<age>[0-9]+ )?(?P<message>.*)/', $str1, $m);    
echo $m['name'] . PHP_EOL;
echo $m['age'] . PHP_EOL;
echo $m['message'] . PHP_EOL;


preg_match('/(?P<name>[a-z]+ )?(?P<age>[0-9]+ )?(?P<message>.*)/', $str2, $m);    
echo $m['name'] . PHP_EOL;
echo $m['age'] . PHP_EOL; // index exists but is now empty
echo $m['message'] . PHP_EOL;

Put a ? directly after your phone number capturing group.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM