【问题标题】:REGEX: match text which containts phrases and it is included between two words正则表达式:匹配包含短语且包含在两个单词之间的文本
【发布时间】:2015-12-02 06:34:25
【问题描述】:


我必须匹配包含一些短语的文本,并且它必须包含在两个常量之间。举个例子吧:
我的上限和下限是相同的,例如“开始”。现在有更多受“START”限制的文本块。我想捕获限制之间的文本,但捕获的文本必须包含一些短语。

START
text1 text1 text1 phrase1 text text
START
text2 text2 phrase2 text2
START
text3 phrase1
START

现在我想用短语 1 捕获文本。它是“text1 text1 text1 phrase1 text text”和“text3 phrase1”。

匹配的文本可能包含 START 词。

我的尝试(没有以正确的方式工作)是:START((.|\s)*?phrase1(.|\s)*?)START。

当START text1 text1 text1 phrase1 text text START 被捕获时,我将其保存到变量中,并使用“START”替换正则表达式方法,因此它看起来像这样:

START
text2 text2 phrase2 text2
START
text3 phrase1
START

在第二个循环之后我得到了:

START
text2 text2 phrase2 text2
START

当我得到第三个循环时(如果它有效,正则表达式应该返回 false)但我崩溃了。在一些在线正则表达式中,它显示不匹配,所以它与模式有问题。

编辑:添加的循环代码

set regEx = new RegEx
//sInputString is my text

regEx.pattern = "START((.|\s)*?phrase1(.|\s)*?)START"
set matches = regEx.Execute(sInputString)

do while (matches.count <> 0)
    sInputString = regEx.Replace(sInputString, "START")
    set matches = regEx.Execute(sInputString) //this line crashes after "ending loop"
    //saving to array
loop

【问题讨论】:

  • 任何特定的语言?
  • 请发布您的代码。我觉得这与你在没有匹配时的处理方式有关
  • 在VBA中使用。它使用 VBScript 正则表达式 5.5 库。我已经添加了代码。您认为(鄙视效率等)该模式应该有效吗?

标签: regex


【解决方案1】:

(.|\s)*? 构造效率非常低,给正则表达式用户带来了很多痛苦。始终将其替换为 .*?(带有单行修饰符)、[\s\S]*? 或展开循环的正则表达式。

在您的情况下,您可以像这样使用展开循环正则表达式:

\bSTART\b([^S]*(?:S(?!TART\b)[^S]*)*)

匹配:

  • \bSTART\b - 一个完整的单词START(如果你不使用完整的单词,你可以省略\b)
  • ([^S]*(?:S(?!TART\b))*) - 捕获组匹配
    • [^S]* - 除S 之外的 0 个或多个字符
    • (?:S(?!TART\b)[^S]*)* - 0 个或多个序列...
      • S(?!TART\b) - S 后面没有 TART 和一个单词边界
      • [^S]* - 除S 之外的 0 个或多个字符

得到

text1 text1 text1 phrase1 text text
text2 text2 phrase2 text2
text3 phrase1

见regex demo

现在,如果您只需要 2 个子字符串,只需在末尾添加 \bSTART\b,它将消耗尾随的 START:

\bSTART\b([^S]*(?:S(?!TART\b)[^S]*)*)\bSTART\b

参见another demo(捕获text1 text1 text1 phrase1 text text 和text3 phrase1)。

第二个正则表达式本质上与(?s)\bSTART\b(.*?)\bSTART\b 相同,但在处理较长的文本时效率更高,但.*? 惰性点匹配(匹配 0 个或更多任何字符,但尽可能少返回一个有效的匹配项) 当子字符串很短时更可取。

最后一点:如果您不需要匹配整个单词,则不必使用单词边界\b。

【讨论】:

  • 修复了一个错误,忘记了[^S]*。
  • 感谢您的回复!明天我会回到这个,因为我现在不能告诉你它是否适合我的目的——它比我展示的要复杂一点——而且因为我对正则表达式完全陌生,所以我不能只看它就说。我在正则表达式演示中处理了一些文本和模式,这对我的任务来说似乎没问题。
猜你喜欢
  • 1970-01-01
  • 2016-12-26
  • 2016-01-14
  • 1970-01-01
  • 2017-02-06
  • 1970-01-01
相关资源
最近更新 更多