Java 一个正则表达式来匹配后面没有某个其他子字符串的子字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2631010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
A regex to match a substring that isn't followed by a certain other substring
提问by Rayne
I need a regex that will match blahfooblah
but not blahfoobarblah
我需要一个匹配blahfooblah
但不匹配的正则表达式blahfoobarblah
I want it to match only foo and everything around foo, as long as it isn't followed by bar.
我希望它只匹配 foo 和 foo 周围的所有内容,只要它后面没有 bar。
I tried using this: foo.*(?<!bar)
which is fairly close, but it matches blahfoobarblah
. The negative look behind needs to match anything and not just bar.
我尝试使用这个:foo.*(?<!bar)
这是相当接近的,但它匹配blahfoobarblah
. 背后的负面外观需要匹配任何东西,而不仅仅是酒吧。
The specific language I'm using is Clojure which uses Java regexes under the hood.
我使用的特定语言是 Clojure,它在底层使用 Java 正则表达式。
EDIT: More specifically, I also need it to pass blahfooblahfoobarblah
but not blahfoobarblahblah
.
编辑:更具体地说,我也需要它通过blahfooblahfoobarblah
但不是blahfoobarblahblah
.
采纳答案by ma?ek
Try:
尝试:
/(?!.*bar)(?=.*foo)^(\w+)$/
Tests:
测试:
blahfooblah # pass
blahfooblahbarfail # fail
somethingfoo # pass
shouldbarfooshouldfail # fail
barfoofail # fail
Regular expression explanation
正则表达式解释
NODE EXPLANATION
--------------------------------------------------------------------------------
(?! look ahead to see if there is not:
--------------------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
bar 'bar'
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
(?= look ahead to see if there is:
--------------------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
foo 'foo'
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
^ the beginning of the string
--------------------------------------------------------------------------------
( group and capture to :
--------------------------------------------------------------------------------
\w+ word characters (a-z, A-Z, 0-9, _) (1 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
) end of
--------------------------------------------------------------------------------
$ before an optional \n, and the end of the
string
Other regex
其他正则表达式
If you only want to exclude bar
when it is directly after foo
, you can use
如果您只想在bar
直接在 之后排除,则foo
可以使用
/(?!.*foobar)(?=.*foo)^(\w+)$/
Edit
编辑
You made an update to your question to make it specific.
您对问题进行了更新以使其具体。
/(?=.*foo(?!bar))^(\w+)$/
New tests
新测试
fooshouldbarpass # pass
butnotfoobarfail # fail
fooshouldpassevenwithfoobar # pass
nofuuhere # fail
New explanation
新解释
(?=.*foo(?!bar))
ensures a foo
is found but is not followed directly bar
(?=.*foo(?!bar))
确保foo
找到 a 但不直接跟随bar
回答by Audie
Use a negative look ahead instead:
使用负面展望代替:
\s*(?!\w*(bar)\w*)\w*(foo)\w*\s*
This worked for me, hope it helps. Good luck!
这对我有用,希望它有所帮助。祝你好运!
回答by stevemegson
To match a foo
following by something that doesn't start with bar
, try
要匹配foo
不以 开头的内容bar
,请尝试
foo(?!bar)
Your version with negative lookbehind is effectively "match a foo
followed by something that doesn't end in bar
". The .*
matches all of barblah
, and the (?<!bar)
looks back at lah
and checks that it doesn't match bar
, which it doesn't, so the whole pattern matches.
您的负面回顾版本实际上是“匹配 afoo
后跟不以bar
”结尾的内容。本.*
场比赛所有的barblah
,和(?<!bar)
长相背部lah
,并检查不匹配bar
,它没有,所以整个模式匹配。
回答by dawg
Your specific match request can be matched by:
您的特定匹配请求可以通过以下方式匹配:
\w+foo(?!bar)\w+
This will match blahfooblahfoobarblah
but not blahfoobarblahblah
.
这将匹配blahfooblahfoobarblah
但不匹配blahfoobarblahblah
。
The problem with your regex of foo.*(?<!bar)
is the .*
after foo
. It matches as many of any characters including characters after bar
.
您的正则表达式的问题foo.*(?<!bar)
是.*
after foo
。它匹配尽可能多的任何字符,包括bar
.
回答by ma?ek
You wrote a comment suggesting you like this to work matching all words in a string rather than the whole string itself.
您写了一条评论,建议您喜欢这样匹配字符串中的所有单词而不是整个字符串本身。
Rather than mashing all of this in a comment, I'm posting it as a new answer.
我没有在评论中混合所有这些,而是将其作为新答案发布。
New Regex
新正则表达式
/(?=\w*foo(?!bar))(\w+)/
Sample text
示例文本
foowithbar fooevenwithfoobar notfoobar foohere notfoobarhere butfooisokherebar notfoobarhere andnofuu needsfoo
foowithbar fooevenwithfoobar notfoobar foohere notfoobarhere butfooisokherebar notfoobarhere andnofuu requiresfoo
Matches
火柴
foowithbar fooevenwithfoobar foohere butfooisokherebar needsfoo
foowithbar fooevenwithfoobar foohere butfooisokherebar需要foo