正则表达式 - 在两个不包含单词的单词之间获取字符串

时间:2011-09-07 11:33:27

标签: regex search word jmeter

我一直在环顾四周,无法实现这一目标。我不是完全的菜鸟。

我需要通过(包括)不包含START的START和END来分隔文本。基本上我找不到一种方法来否定整个单词而不使用高级的东西。

示例字符串:

  

abcSTARTabcSTARTabcENDabc

预期结果:

  

STARTabcEND

不好:

  

STARTabcSTARTabcEND

我不能使用向后搜索的东西。我在这里测试我的正则表达式:www.regextester.com

感谢您的任何建议。

5 个答案:

答案 0 :(得分:10)

试试这个

START(?!.*START).*?END

here online on Regexr

(?!.*START)是一个负面的预测。它确保单词“START”不跟随

.*?是所有角色的非贪婪匹配,直到下一个“结束”。它需要,因为负向前瞻只是向前看并且没有捕获任何东西(零长度断言)

更新

我想了一下,上面的解决方案是匹配到第一个“结束”。如果不想这样做(因为你要从内容中排除START),那就使用贪心版本

START(?!.*START).*END

这将匹配到最后一个“结束”。

答案 1 :(得分:4)

真正的行人解决方案是START(([^S]|S*S[^ST]|ST[^A]|STA[^R]|STAR[^T])*(S(T(AR?)?)?)?)END。现代正则表达式的味道具有负面断言,这更加优雅,但我将您对“向后搜索”的评论解释为可能意味着您不能或不想使用此功能。

更新:为了完整起见,请注意以上内容对于结束分隔符是贪婪的。要仅捕获最短的字符串,请将否定扩展为覆盖结束分隔符 - START(([^ES]|E*E[^ENS]|EN[^DS]|S*S[^STE]|ST[^AE]|STA[^RE]|STAR[^TE])*(S(T(AR?)?)?|EN?)?)END。但是,这可能会超过大多数文化中的折磨门槛。

错误修复:此答案的先前版本存在错误,因为SSTART可能是匹配的一部分(第二个S将匹配{{1}等等)。我修复此问题,但在[^T]中添加S并在非可选[^ST]之前添加S*,以允许S的任意重复。 / p>

答案 2 :(得分:4)

START(?:(?!START).)*END

可以使用任意数量的START...END对。要在Python中演示:

>>> import re
>>> a = "abcSTARTdefENDghiSTARTjlkENDopqSTARTrstSTARTuvwENDxyz"
>>> re.findall(r"START(?:(?!START).)*END", a)
['STARTdefEND', 'STARTjlkEND', 'STARTuvwEND']

如果您只关心STARTEND之间的内容,请使用以下内容:

(?<=START)(?:(?!START).)*(?=END)

在此处查看:

>>> re.findall(r"(?<=START)(?:(?!START).)*(?=END)", a)
['def', 'jlk', 'uvw']

答案 3 :(得分:2)

我是否可以建议Tim Pietzcker的解决方案可能有所改进? 在我看来,START(?:(?!START).)*?END更好,以便只抓住START紧跟一个END,其间没有任何STARTEND。我正在使用.NET,Tim的解决方案也匹配START END END。至少在我个人的情况下,这不是必需的。

答案 4 :(得分:0)

[编辑:我已经离开这篇文章了解有关捕获组的信息,但我给出的主要解决方案不正确。 <击> (?:START)((?:[^S]|S[^T]|ST[^A]|STA[^R]|STAR[^T])*)(?:END) 正如评论中所指出的那样行不通;我忘记了忽略的字符无法删除,因此你需要像...... |STA(?![^R])|这样的东西仍然允许该字符成为END的一部分,从而失败了诸如STARTSTAEND之类的东西;所以这显然是一个更好的选择;以下内容应显示使用捕获组的正确方法......]

使用带有捕获组的“零宽度负向前瞻”运算符“?!”给出的答案是:(?:START)((?!.*START).*)(?:END)使用$ 1替换替换内部文本。如果您想要捕获START和END标记,可以(START)((?!.*START).*)(END)通过添加/删除()或{{1}来提供$ 1 = START $ 2 =文本和$ 3 = END或其他各种排列}第

如果您使用它进行搜索和替换,那么您可以这样做,比如BEGIN $ 1FINISH。所以,如果你开始:

?:

你会得到abcSTARTdefSTARTghiENDjkl作为捕获组1,并用BEGIN $ 1FINISH替换会给你以下内容:

ghi

只有在正确配对时才允许您更改START / END令牌。

每个abcSTARTdefBEGINghiFINISHjkl都是一个群组,但是我为每个(x)添加了(?:x),除了中间标记为非捕获组;我没有?:的唯一一个是中间人;但是,如果你想要移动它们或者你有什么东西,你也可以想象一下捕获BEGIN / END标记。

有关Java正则表达式的完整详细信息,请参阅Java regex documentation