【问题标题】:Can the if part use things other than lookaround and backreference?if 部分可以使用环视和反向引用以外的东西吗?
【发布时间】:2014-06-09 15:28:18
【问题描述】:

我正在从http://www.regular-expressions.info/conditional.html 学习正则表达式中的条件。

似乎只提到 if 部分使用环视和反向引用。 if 部分可以使用环视和反向引用以外的东西吗?

if 部分可以使用任何表达式吗?

请注意,我并不局限于特定的编程语言。只是在一般设置中,作为链接。

谢谢。

【问题讨论】:

  • 你能举个例子说明你想做什么吗?
  • 尝试理解正则表达式中的条件,以便我知道什么时候可以使用它。
  • 您也可以将if/then/elsenegative/positive loohahead/lookbehinds 一起使用,这里有一个快速概述:regular-expressions.info/refadv.html
  • 我不认为您可以使用其他任何东西,但是您可以通过消极/积极的环视和交替 (|) 来做一些非常邪恶的事情。

标签: regex


【解决方案1】:

是的,例如使用 Perl/PCRE,您可以测试捕获组的存在(这也适用于 .net)

(?(2)...|...)

(?(<group>)...|...)  # for a named capture

或者如果已经达到递归级别:

(?(R)...|...)

(?(R2)...|...)


如果您想在字符串中的特定位置知道子模式是否稍后会匹配,方法是使用您在问题中描述的前瞻,例如字符串aaabbbcccaaazzz
aaa(?(?=...ccc)bbb|zzz) 

aaa(?(?=...ccc)(bbb|zzz))  # with a capture

但大多数时候,您不需要这样做,需要一个简单的替换:

aaa(?:bbbccc|zzz)

或者如果您需要使用相同的编号或名称进行捕获 (Branch reset feature) (?|...|...|...|...)(每个备选方案中的捕获具有相同的编号)

aaa(?|(bbb)ccc|(zzz))

同名:

aaa(?|(?<name>bbb)ccc|(?<name>zzz)) # but writing the name of the capture
                                    # a second time is not needed: 
aaa(?|(?<name>bbb)ccc|(zzz)) 

或同名但没有分支重置(仅限 PCRE):

(?J)aaa(?:(?<name>bbb)ccc|(?<name>zzz))

(?J) 允许重复命名捕获)

.net 允许使用重复的命名捕获。

【讨论】:

  • 谢谢。当我提到“反向引用”时,我的意思是测试捕获组的存在。 (1) 那么当使用反向引用作为if部分时,组必须总是在之前被捕获(类似于lookbehind),而不是后来被捕获(类似于lookahead)? (2) 那么其他正则表达式不能用作if部分的条件吗?
  • @Tim:你可以在里面捕捉到它:前瞻!更严重的是,分支重置功能或具有交替的简单组可能会对您有所帮助。你能描述一个具体的案例吗?
  • 我的意思是只使用捕获的组,而不是使用前瞻,我们是否仍然可以在前方某处测试组的存在(不一定在前方,即与前瞻不同)?
  • @Tim:不,你不能,捕获组必须在之前定义,这就是为什么我建议你使用简单的替代或分支重置,如果你需要进行任何捕获在两种(或几种)情况下使用相同的号码/名称。不要忘记正则表达式引擎从左到右处理字符串(默认情况下)。
  • @CasimiretHippolyte 不错的答案 +1 也用于完成相对位置,例如(?(-3)) 但你知道 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
  • 2015-07-07
  • 2013-07-26
  • 1970-01-01
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多