3 回答

TA贡献1828条经验 获得超4个赞
你可以使用
(?<=\[)[^]\s]+(?=])
请参阅正则表达式和PHP 演示。请注意,该$matches
结构在模式中没有捕获组时更清晰,所有上下文都使用非消耗性环视检查。
细节
(?<=\[)
[
- 需要立即在当前位置左侧的正向后视[^]\s]+
- 除了]
(不需要转义它,因为它是否定字符类中的第一个字符)和空格之外的1+ 个字符(?=])
]
- 需要紧靠当前位置右侧的正向前瞻(]
在字符类之外并不特殊)。
$arr = ['[text* your-name]','[email* your-email]','[text your-subject]','[textarea your-message]','[submit "Verzenden"]','[your-subject]','[your-name]','[your-email]','[your-message]'];
foreach ($arr as $s) {
if (preg_match_all('~(?<=\[)[^]\s]+(?=])~', $s, $matches)) {
print_r($matches[0]);
}
}
输出:
Array
(
[0] => your-subject
)
Array
(
[0] => your-name
)
Array
(
[0] => your-email
)
Array
(
[0] => your-message
)

TA贡献1862条经验 获得超6个赞
从您当前的模式开始,您所要做的就是从字符类中排除空格或所有空白字符,并检查后面是否有右方括号。所以(?<=\[)([^]\s]+)(?=])
在整个比赛或捕获组中的结果(这使它无用)。
但是你可以写一个更好的模式,更简单,更高效:\[([^]\s]+)]
。演示
更简单,因为有一个捕获组,你不必使用环视来提取你想要的没有括号的内容。它也更短,更容易理解。
由于两个启动优化,效率更高:
第一个也是最重要的:当模式以文字字符串(此处为左括号)开头时,快速算法会在字符串中搜索该文字字符串在主题字符串中出现的所有位置,并且只会在这些位置测试该模式. 否则,如果您将此括号括在后视中就是这种情况,则此启动优化是不可能的,并且将在主题字符串中的每个位置测试该模式。
第二种叫做自动占有。当最终回溯不会改变结果时,它会在编译时自动使量词占有所有格。比如,停留的时候
a*b
变成。在我们的例子中,由于字符类不包括右括号,因此变为. 具体而言,当找到空格而不是右括号时,贪婪量词不会返回字符来尝试其他可能性,模式失败,正则表达式引擎会在下一个位置尝试模式。再一次,将括号放在前瞻中会禁用此优化。a*+b
a.*b
a.*b
[^]\s]
[^]\s]+]
[^]\s]++]
但是为什么环视会禁用这些优化呢?原因很简单,这些优化需要研究模式,所以为了让这些分析保持快速,它们仅限于简单的情况。(请注意,捕获组不会干扰自动占有。)
如果你绝对想避免捕获组但又想保留这两个优化,那么没有什么可以禁止写的:
\[\K[^]\s]++(?=])
演示
或更有趣:
\[(?=[^]\s]++\K])
演示
这两个模式以文字开头[
,所有格量词是手动添加的。
- 3 回答
- 0 关注
- 117 浏览
添加回答
举报