取这个正则表达式:/^[^abc]/。这将匹配字符串开头的任何单个字符,除了a、b或c。
如果在后面添加*–/^[^abc]*/–正则表达式将继续向结果中添加每个后续字符,直到它遇到a–或b–或c–为止。
例如,对于源字符串"qwerty qwerty whatever abc hello",表达式将与"qwerty qwerty wh"匹配。
但是如果我想要匹配的字符串是"qwerty qwerty whatever",怎么办?
…换句话说,我怎样才能匹配(但不包括)精确序列"abc"?
- 你说的match but not including是什么意思?
- 我的意思是我想和"qwerty qwerty whatever"匹配——不包括"abc"。换句话说,我不希望得到的匹配是"qwerty qwerty whatever abc"。
- 在javascript中,您可以只使用do string.split('abc')[0]。当然不是这个问题的官方答案,但我发现它比regex更直接。
您没有指定要使用的regex的口味,但这将在任何一个最受欢迎的,可以被认为是"完整的"。
它是如何工作的
.+?部分是.+的非贪婪版本(一个或多个什么都行。当我们使用.+时,发动机基本上可以匹配所有部件。然后,如果regex中还有其他内容,它将逐步返回正在尝试匹配以下部分。这是贪婪的行为,尽可能满足的意思。
当使用.+?时,不要一次匹配全部,而是返回其他条件(如果有),引擎将按匹配下一个字符步骤,直到regex的后续部分匹配为止(如果有则再次匹配)。这是不贪婪的,意思是尽可能少的匹配满足。
1 2 3 4 5
| /.+X/ ~"abcXabcXabcX" /.+/ ~"abcXabcXabcX"
^^^^^^^^^^^^ ^^^^^^^^^^^^
/.+?X/ ~"abcXabcXabcX" /.+?/ ~"abcXabcXabcX"
^^^^ ^ |
接下来我们有了(?={contents}),一个零宽度断言,环顾四周。此分组结构与内容,但不算作匹配的字符(零宽度)。它只有匹配或不匹配时才返回(断言)。
因此,在其他术语中,regex /.+?(?=abc)/表示:
Match any characters as few as possible until a "abc" is found,
without counting the"abc".
- 如果要捕获换行符,这可能不适用。
- 代码功能的出色描述。
- .+?和.*有什么区别?
- @robbie0630 +表示1或更多,其中*表示0或更多。包含/排除?将使其贪婪或非贪婪。
- 我们如何在这里放置或条件?也就是说,检查ABC或XYZ?
- @测试人员Joe2/+??= ABC·XYZ)
- @约翰伦斯比-谢谢。这个?+??<=abc_xyz)也可以获取abc/xyz文本。
- 我试图在Mac上使用SED,但不支持使用"?"这样,我切换到Perl。
- 这在多行中不起作用。这个问题要求"任何东西"
- @abhinandandandubey您可以替换。有了[^]它就可以工作了。
- @如果需要使用换行符,可以将/s标志添加到regex。
- 我注意到,如果您要查找的模式不存在,则无法选择任何内容,相反,如果您使用^(?:(?!abc)(?!def).)*,则可以链接以排除不需要的模式,即使该模式不存在,它仍将根据需要获取所有内容。
- 空白的还是空白的?雷杰克斯是干什么的?
如果你想捕捉到"ABC"之前的一切:
说明:
( )捕获括号内的表达式,以便使用$1和$2等进行访问。
^匹配行首
.*匹配任何内容,?不贪婪地(匹配所需的最小字符数)-[1]
[1]之所以需要这样做,是因为在以下字符串中:
1
| whatever whatever something abc something abc |
默认情况下,正则表达式是贪婪的,这意味着它将尽可能匹配。因此,/^.*abc/将匹配"任何ABC某物"。添加非贪婪量词?,使得regex只匹配"随便什么"。
- 谢谢,但你的比赛中确实有ABC。换言之,结果匹配是"无论什么样的ABC"。
- 你能解释一下你到底想做什么吗?如果你的场景是:(a)你想要得到"abc"之前的所有东西——只需要在你想要捕获的东西周围使用括号。(B)您希望将字符串与"abc"匹配——无论如何,您必须检查abc,因此它必须是regex的一部分,而不管怎样。你还能怎么检查它在那里?
- sed似乎不支持非贪婪匹配,也不支持环顾((?=...))。我还能做什么?示例命令:echo"ONE: two,three, FOUR FIVE, six,seven" | sed -n -r"s/^ONE: (.+?), .*/\1/p"返回two,three, FOUR FIVE,但我希望two,three能…
- @codemanx你应该把它作为你自己的独立问题,而不是评论,特别是因为它是关于sed的。也就是说,为了解决你的问题:你可能想看看这个问题的答案。另外请注意,在您的示例中,非贪心感知的解释器只返回two,而不是two,three。
- 你说得对,不过谢谢你的链接。为什么它只返回two?two,three中有一个逗号,但没有空格。
- 噢,你说得对。我错过了你的正则表达式中的空格。确认:echo"ONE: two,three, FOUR FIVE, six,seven" | perl -pe 's/^ONE: (.+?), .*/\1/'给two,three。
- 这就是每个regexp答案都应该看起来的样子-所有部分的示例和解释…
- 在记事本+(*)中,ABC将找到"ABC"之前的任何内容,包括ABC。
- "贪婪"的提法非常有用,谢谢!我做了这么长时间贪婪的regex,时间来改变。
- 我们如何在这里放置或条件?也就是说,检查ABC或XYZ?
正如@jared ng和@issun指出的,解决此类regex的关键是"将所有内容匹配到某个单词或子字符串"或"在某个单词或子字符串之后匹配所有内容",这称为"lookaround"零长度断言。在这里阅读更多关于它们的信息。
在您的特定情况下,可以通过积极的展望来解决。一幅画胜过千言万语。请参见屏幕截图中的详细说明。
你需要的是看看像.+? (?=abc)这样的断言。
参见:lookahead和lookbehind零长度断言
注意,[abc]与abc不同。括号内不是字符串-每个字符只是一种可能性。在括号外,它变成了字符串。
这对于regex是有意义的。
确切的单词可以从以下regex命令中获得:
("(.*?)")/g
在这里,我们可以从全局中得到双引号内的确切单词。例如,如果我们的搜索文本是,
这是"双引号"单词的示例
然后我们将从那个句子中得到"双引号"。
- 欢迎使用StackOverflow,感谢您的帮助。我发现很难看出这对问题中的目标有什么帮助。你能详细解释一下吗?你能把它应用到给定的例子中吗?你似乎专注于处理",在我看来,这与问题无关。
- 嗨,我已经解释了如何在特殊字符之间插入单词或句子。在这里,我们的问题也是"在特殊字符序列之前的任何事情"。所以我试着用双引号在这里解释。谢谢。
对于Java中的正则表达式,我相信在大多数正则表达式引擎中,如果要包含最后一部分,这将是可行的:
例如,在此行中:
1
| I have this very nice senabctence |
选择"abc"之前的所有字符,还包括abc
使用我们的regex,结果将是:I have this very nice senabc。
测试:https://regex101.com/r/mx51ru/1
在寻求帮助解决我的问题后,我结束了这个stackoverflow问题,但没有找到解决方法:(
所以我必须即兴发挥…过了一段时间,我终于找到了我需要的雷杰克斯:
如您所见,我需要在"GRP BPS"文件夹之前最多有一个文件夹,而不包括最后一个破折号。并且在"grp bps"文件夹之后至少要有一个文件夹。
我相信你需要子表达式。如果我记得对的话,你可以用普通的()括号来表示子表达式。
本部分来自GREP手册:
1 2 3 4 5
| Back References and Subexpressions
The back-reference
, where n is a single digit, matches the substring
previously matched by the nth parenthesized subexpression of the
regular expression. |
做一些像^[^(abc)]应该做的事情。
- 对不起,那不行。把ABC放在括号里似乎没有什么区别。它们仍然被视为"A或B或C"。
$标志着一个字符串的结束,所以类似这样的东西应该是有效的:[[^abc]*]$在这里你要寻找的任何东西都不是在abc的任何迭代中结束的,但是它必须在结束时
另外,如果您在regex中使用脚本语言(如php或js),它们有一个搜索函数,当它第一次遇到模式时停止(您可以指定从左开始或从右开始,或者使用php,您可以执行内爆来镜像字符串)。
试试这个
查询:
1
| select REGEXP_REPLACE ('abcdefghijklmn','.+?efg', '') FROM dual; |
输出: