我在C#程序中具有以下正则表达式,并且难以理解它:
(?<=#)[^#]+(?=#)
我将其分解为我认为的理解:
(?<=#) a group, matching a hash. what's `?<=`?
[^#]+ one or more non-hashes (used to achieve non-greediness)
(?=#) another group, matching a hash. what's the `?=`?
所以我的问题是
?<=
和?<
部分。通过阅读MSDN,?<name>
用于命名组,但是在这种情况下,尖括号永远不会关闭。我在文档中找不到
?=
,搜索起来确实很困难,因为搜索引擎通常会忽略那些特殊字符。
最佳答案
它们称为环顾四周;它们允许您断言某个模式是否匹配,而无需实际进行匹配。有4种基本的解决方法:
pattern
...(?=pattern)
-...在当前位置的右边(向前看)(?<=pattern)
-...在当前位置的左侧(向后看)pattern
(?!pattern)
-...在右侧(?<!pattern)
-...到左侧作为一个简单的提醒,请环顾一下:
=
为正,!
为负<
在后面,否则向前看引用文献
但是为什么要使用环顾四周?
有人可能会争辩说,不需要在上述模式中环顾四周,并且
#([^#]+)#
可以很好地完成工作(提取\1
捕获的字符串以获取non-#
)。不完全的。区别在于,由于环视与
#
不匹配,因此下次尝试查找匹配项时,它可以再次“使用”。简单地说,环顾四周允许“匹配项”重叠。考虑以下输入字符串:
and #one# and #two# and #three#four#
现在,
#([a-z]+)#
将给出以下匹配项(as seen on rubular.com):and #one# and #two# and #three#four#
\___/ \___/ \_____/
将此与
(?<=#)[a-z]+(?=#)
进行比较,它匹配:and #one# and #two# and #three#four#
\_/ \_/ \___/ \__/
不幸的是,这不能在rubular.com上得到证明,因为它不支持向后看。但是,它确实支持先行,因此我们可以对
#([a-z]+)(?=#)
进行类似的操作,该匹配项(as seen on rubular.com):and #one# and #two# and #three#four#
\__/ \__/ \____/\___/
引用文献
关于regex - 正则表达式 ‘(?<=#)[^#]+(?=#)’如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3092797/