我一直在环顾四周,无法实现这一目标。我不是完全的菜鸟。
我需要通过(包括)不包含START的START和END来分隔文本。基本上我找不到一种方法来否定整个单词而不使用高级的东西。
示例字符串:
abcSTARTabcSTARTabcENDabc
预期结果:
STARTabcEND
不好:
STARTabcSTARTabcEND
我不能使用向后搜索的东西。我在这里测试我的正则表达式:www.regextester.com
感谢您的任何建议。
答案 0 :(得分:10)
试试这个
START(?!.*START).*?END
(?!.*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']
如果您只关心START
和END
之间的内容,请使用以下内容:
(?<=START)(?:(?!START).)*(?=END)
在此处查看:
>>> re.findall(r"(?<=START)(?:(?!START).)*(?=END)", a)
['def', 'jlk', 'uvw']
答案 3 :(得分:2)
我是否可以建议Tim Pietzcker的解决方案可能有所改进?
在我看来,START(?:(?!START).)*?END
更好,以便只抓住START
紧跟一个END
,其间没有任何START
或END
。我正在使用.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。