php - PHP:preg_match 用于“一些多个单词字符串”+ [\s* +”"]
问题描述
需要以下列可能形式出现的解析字符串:
Some User Name
Some User Name <user.mail@address>
因此用户名(多个单词)始终存在,但电子邮件是可选的,并且包含在尖括号中。
我需要从那些中抓住:
- 用户名,一个字符串,多个单词用\s或\h分隔
- 在不带尖括号的下一个电子邮件地址(如果存在)之后。如果未指定电子邮件地址,则生成的子掩码数组应为空(但始终存在于结果中)。
我尝试了一些变化
preg_match('/^(.*?)\s*(?:\<(.*)\>)?$/s', $in, $out)
但这不起作用。
谢谢有人帮助我。
解决方案
要获取由可选电子邮件地址分隔的所有单独单词\h
,您可以使用\G
锚来获取迭代匹配,在上一个匹配结束时断言位置。
(?|^(\w+)|\G(?!^)\h+(\w+))(?:\h+<([^<>\r\n]+)>$)?
解释
(?|
分支重置组(保留单词$matches[1]
)^(\w+)
字符串开头,匹配第 1组中的 1+ 个单词字符|
或者\G(?!^)
在上一场比赛结束时断言位置,而不是在开始时\h+(\w+)
匹配组 1中的 1+ 个水平空白字符
)
关闭分支重置组(?:
非捕获组\h+
匹配 1+ 个水平空白字符<([^<>\r\n]+)>$
<>
在字符串末尾捕获第2 组中的电子邮件地址
)?
关闭非捕获组并使其可选
使用preg_match_all获取所有值。
默认标志是PREG_PATTERN_ORDER
:
排序结果,使得 $matches[0] 是一个完整模式匹配的数组,$matches[1] 是一个由第一个带括号的子模式匹配的字符串数组,依此类推。
文字在$matches[1]
,电子邮件在$matches2
如果电子邮件不存在,则数组将存在,但为空。
您可以使用array_filter从电子邮件数组中删除空条目。
Example code
$pattern = "~(?|^(\w+)|\G(?!^)\h+(\w+))(?:\h+<([^<>\r\n]+)>$)?~";
$strings = [
"Some User Name ",
"Some User Name <user.mail@address>"
];
foreach ($strings as $str) {
preg_match_all($pattern, $str, $matches);
print_r($matches[1]);
print_r(array_filter($matches[2]));
}
输出
Array
(
[0] => Some
[1] => User
[2] => Name
)
Array
(
)
Array
(
[0] => Some
[1] => User
[2] => Name
)
Array
(
[2] => user.mail@address
)
推荐阅读
- linux - 未找到 在此服务器上未找到请求的 URL
- ssh - Databricks:使用 SSH 连接连接到 Redshift 集群
- django - request.session['pk'] = user.pk AttributeError: 'QuerySet' 对象没有属性 'pk'
- javascript - 使用 d3 在可缩放的圆形包装图中添加描述文本和链接
- nuget - 如何在视觉中通过 Nuget 安装预览或 RC 包?
- .net - .NET:SqlDataAdapter:DataTable:输出参数:返回 JSON
- javascript - 将点击方法内的数据传递给包含角度组件
- docker - Docker compose 和 Fargate 回滚
- javascript - 关于什么应该是基本对象的打字稿错误
- flutter - 颤振显示表情符号