【发布时间】:2011-06-19 23:20:23
【问题描述】:
假设我有以下文本:
__This_is__ a __test__
使用两个下划线表示斜体。所以我希望This_is 和test 是斜体。逻辑规定,两个连续双下划线之间的任何文本都应为斜体,包括可能存在的任何其他数量的下划线。我有:
__([^_]+)__
第 1 组中“不是两个连续的下划线”的等价物是什么?谢谢。
【问题讨论】:
假设我有以下文本:
__This_is__ a __test__
使用两个下划线表示斜体。所以我希望This_is 和test 是斜体。逻辑规定,两个连续双下划线之间的任何文本都应为斜体,包括可能存在的任何其他数量的下划线。我有:
__([^_]+)__
第 1 组中“不是两个连续的下划线”的等价物是什么?谢谢。
【问题讨论】:
一个选项是匹配两个下划线:
__
然后负向向前看,看看当前位置前面是否没有两个下划线:
__(?!__)
如果不是这样,匹配任意字符:
__(?!__).
并重复前一次或多次:
__((?!__).)+
最后匹配另外两个下划线:
__((?!__).)+__
这是最终的解决方案。
一个小演示:
<?php
$text = '__This_is__ a __test__';
preg_match_all('/__(?:(?!__).)+__/', $text, $matches);
print_r($matches);
?>
产生:
Array
(
[0] => Array
(
[0] => __This_is__
[1] => __test__
)
)
可以在Ideone上看到。
请注意,我在演示中使用了非捕获组,否则输出将如下所示:
Array
(
[0] => Array
(
[0] => __This_is__
[1] => __test__
)
[1] => Array
(
[0] => s
[1] => t
)
)
即((?!__).) 匹配的最后一个字符将在第 1 组中被捕获。
有关群组的更多信息,请参阅:http://www.regular-expressions.info/brackets.html
【讨论】:
__(?:(?!__).)+__ 中多余的 ?: 是什么?
(?:...) 是非捕获组,而 (...) 捕获内容以供以后重用。由于您没有重复使用重复的元素,因此您可以使用前一种构造并获得一点效率。
$text = '__This_is__ a __test__';
preg_match_all('/(__([\w]+)__)/', $text, $matches);
print_r($matches);
【讨论】: