给出以下示例输入文本:
{{A1 | def | ghi | jkl}}你好世界。 {{A2 | mno}}再见世界。
如何创建正则表达式模式以仅匹配{{ ... }}
的第一个实例(即仅{{A1|def|ghi|jkl}}
)。 A1
和A2
是固定输入,def
,ghi
,jkl
和mno
可以是任何内容。
我试过这个:
\{\{A1\|(.*)\|(.*)\|(.*)\}\}
但这会返回所有内容({{A1|def|ghi|jkl}}hello world. {{A2|mno}}
)。
请注意,def
或ghi
或jkl
或mno
可以是数字,英文字母或其他语言(例如中文/日文/韩文)。
答案 0 :(得分:3)
有点不清楚你想要完成什么。起初,我认为你的问题只是当你真正想要的是A1
或A2
部分时,你得到了整个事情。如果是这样,这就是答案:
由于您未指定使用哪种正则表达式,因此很难确定。如果您使用的是支持环视的版本,您可以执行以下操作:
(?<={{)\w+(?=(\|[^|}]*)+}})
以下是模式的含义:
(?<={{)
- 这是一个积极的后视表达式,这意味着它断言任何匹配必须以某些字符开头。在这种情况下,字符为{{
。\w+
- 这是我们匹配的实际部分。在这种情况下,它是一个或多个单词字符。 \w
是一个特殊的角色类。但这取决于您使用的正则表达式引擎。 [A-Z][0-9]
之类的东西可能更合适,具体取决于您的需求。(?=(\|[^|}]*)+}})
- 这是一个积极的前瞻表达。这意味着它断言任何匹配必须遵循一些特定的字符模式。在这种情况下,它正在寻找匹配(\|[^|}]*)+}}
。但是,如果无法环顾四周,那么您可以将其与捕获组匹配,如下所示:
{{(\w+)(\|[^|}]*)+}}
如果您这样做,则需要为每场比赛读取第一组的值。
只要找到第一场比赛,这实际上取决于您使用的工具或语言。大多数正则表达式引擎默认只找到第一个匹配项,并且只在指定了全局修饰符时才找到其他匹配项(最后通常为/g
)。
然而,现在,在编辑了你的问题并且更好地理解你的意思之后,我认为你真正的问题是贪婪。正则表达式中的重复(例如*
)默认情况下是贪婪的。这意味着他们将捕获尽可能多的文本并仍然匹配。在这种情况下,您不希望它找到最长的匹配。在这种情况下,您希望它找到最短的匹配。你可以简单地通过使重复变得懒惰(即非贪婪)来做到这一点。为此,只需在?
之后添加*
即可。例如:
\{\{A1\|(.*?)\|(.*?)\|(.*?)\}\}
然而,这不是很有效率。如果要经常使用此模式或在大输入上使用,最好使用限制性更强的字符类,例如[^}|]
而不是.
,这样就不需要延迟修饰符。例如:
\{\{A1\|([^}|]*)\|([^}|]*)\|([^}|]*)\}\}
或者更简单:
{{A1(\|([^}|]*)){3}}}
答案 1 :(得分:0)
你的模式的问题很简单,你已经让所有*
量词都贪婪了。他们尽可能多地匹配字符串(同时仍允许整个模式匹配)。只是让他们不贪婪*?
:
\{\{A1\|(.*?)\|(.*?)\|(.*?)\}\}