在正则表达式中使捕获组可选

时间:2014-10-26 19:50:28

标签: php regex

我有一个自动生成的电子邮件,我正在尝试将其解析为导入应用程序的字段。如果所有字段都存在,我有一个工作正则表达式。但是,情况并非总是如此。具体来说,电话号码有时会丢失。

$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.
}

如何在电话号码存在时提取电话号码,但在$import->phone中删除NULL?

请注意,“状态”在正则表达式中仅用于帮助填写邮政编码的位置。

2 个答案:

答案 0 :(得分:1)

您可以使用(?P<name> ...)为抓取组a name ?提供可选项。

我准备了一个简化的例子。我们假设您有一个字符串:

name [age (optional)] message:

您可以使用以下正则表达式解析它:

// 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;

答案 1 :(得分:0)

放一个?直接在您的电话号码捕获组之后。