【问题标题】:Using regex to match string between two strings使用正则表达式匹配两个字符串之间的字符串
【发布时间】:2010-01-02 06:35:51
【问题描述】:

我如何使用正则表达式来匹配两个字符串之间的文本,这两个字符串本身包含在两个其他字符串中,并且内部和外部封闭字符串之间有任意数量的文本?

例如,我有这样的文字:

outer-start 一些文本 inner-start text-that-i-want inner-end 一些更多文字外端

在这种情况下,我想要 text-that-i-want,因为它位于 inner-startinner-end 之间,它们位于 outer-startouter-end 之间。

如果我有

一些文本 inner-start text-that-i-want inner-end 一些文本 outer-end强>

那么我不想要 text-that-i-want,因为虽然它在 inner-startinner-end 之间, 没有 outer-start 包围这些字符串。

同样,如果我有

outer-start 一些文本 text-that-i-want inner-end 一些更多文本 outer-end强>

再一次,我不想要text-that-i-want,因为没有封闭的inner-start,虽然有封闭的outer -startouter-end 字符串。

假设 outer-startinner-startinner-endouter-end 只会曾经被用于封闭/分隔的目的。

我认为我可以通过执行两遍正则表达式匹配来做到这一点,即查找 outer-startouter-end 之间的任何数据,然后在该数据查找 inner-startinner-end 之间的任何文本(如果确实存在这些字符串),但我想知道它是否可以一次性完成.

【问题讨论】:

  • 真实示例而不是这些“外部开始”占位符可能会为您提供更好的答案。

标签: regex language-agnostic match nested


【解决方案1】:
/outer-start.*?inner-start(.*?)inner-end.*?outer-end/

当有多个“我想要的文本”时,您需要使用最小匹配来防止正则表达式引擎出现故障,例如:

“外部开始一些文本内部开始第一个文本我想要内部结束一些更多文本外部结束外部开始一些文本内部开始第二个文本我想要内部结束更多文本外端"

如果没有最小匹配,你会得到令人费解的单一匹配,“second-text-that-i-want”。

.*?意思是“吃零个或多个字符,但只需要使表达式的其余部分匹配。使用?,只要表达式的其余部分匹配,正则表达式引擎就会吃尽可能多的字符。

【讨论】:

  • 事实上,通过贪婪匹配,你会得到 "first-text-that-i-want inner-end some more text outer-end outer-start some text inner-start second- text-that-i-want" 在捕获组中。
  • Michal:不,第一个(非分组).* 吃掉了你引用的大部分文字。
  • 哎哟……对了。我的不好,谢谢指正。事实上,这是删除我的答案并为此 +1 的好理由。
  • @Wayne:你为什么不编辑在顶部的模式中包含惰性版本(。*?)?正如您的回答所示,您已经很好地解释了为什么 .*?比 .* 更受欢迎,但在高可见性示例中使用 .*。 :-)
  • @Michael:哦,我太粗心了。我测试了好的和坏的正则表达式,但是当我发布答案时,我复制并粘贴了坏的。糟糕的程序员,没有cookie!谢谢你看着我的背影。
【解决方案2】:

我想你可以这样做:


outer-start .*? inner-start (.*?) inner-end .*? outer-end

【讨论】:

  • 看起来 Brian 打败了我发布这个解决方案。我加入问号的原因是为了让你免于使用贪婪的正则表达式的麻烦。您可能希望包含它们。
猜你喜欢
  • 1970-01-01
  • 2012-09-26
  • 1970-01-01
  • 2020-10-19
  • 1970-01-01
  • 2011-08-31
  • 1970-01-01
相关资源
最近更新 更多