正则表达式 - 匹配不包含指定字符串的子串

3
使用正则表达式\*\*([^\*]*)\*\*可以匹配多个在**内的文本组,例如:this **is** a **test**返回istest
给出字符串that's **right * a test**,如何调整表达式以返回right * a test?如何将表达式排除两个*而不仅仅是一个? http://regex101.com/r/aD3pC2

3
这需要翻译成哪种语言?不同编程语言之间的正则表达式是有区别的。 - John Dvorak
5个回答

8
您可以使用勉强量词.*?
\*\*.*?\*\*

假设它被你的正则表达式引擎支持。


1
使用一个or
\*\*((?:[^*]|\*[^*])*)\*\*

在匹配组中,这将匹配任何不是星号或者星号后面跟着非星号的字符。第一个双星号(`**`)的出现被认为是字符串字面量的结束。如果字符串内容以星号结尾(例如 `**my string ends with a star***`),我的正则表达式将不包括最后一个星号在匹配中(所以字符串内容将仅为“`my string ends with a star`”)。但我认为这样描述是有效的。
然而,如果字符串字面量以星号开头,例如 `***Star Power!**`,它将包括星号在字符串内容中,我认为这也是有效的,因为第一个 `**` 的出现标志着字符串字面量的开始,而接下来的单个 `*` 只是内容的一部分。
此外,请注意,在字符类中您不需要转义星号(在大多数实现中)。

然而,它将匹配字符串字面量开头的单个星号,例如***这样的字符串** - John Dvorak
结尾的星号不起作用(可能不应该)...开头的星号起作用(可能应该)...什么? - John Dvorak
2
如果字符串内容以星号结尾(例如 **我的字符串以星号结尾***),我的正则表达式将不会包括匹配中的最后一个星号,但我认为这是有效的,因为第一次出现的 ** 终止了字符串字面量。然而,如果字符串字面量以星号开头,就像你指出的那个,它将包括字符串内容中的星号,我认为这也是有效的,因为第一次出现的 ** 标记了字符串字面量的开始,接下来的单个 * 只是内容的一部分。 - brianmearns
@sh1ftst0rm,你的解释真的很好,你可能想把它编辑到你的答案中。 - Michelle

1
为避免所有繁琐的转义,我将使用这个正则表达式:
([*][*])(.*?)\1

我希望你能够获取匹配的第二个组。

演示链接: http://www.rubular.com/r/hJY1eXnLty


1
我非常喜欢使用方括号而不是转义。这确实使我的眼睛更容易解析。 - brianmearns

0
你可以使用这个模式:
 \*\*((?:[^*]|[^*]\*[^*])*)\*\*

它将匹配任何一对*字符,后跟零个或多个除*以外的任何字符或被字符*包围的字符(除*以外),然后再跟另一对*字符。


如果字符串字面量以星号开头,例如*like this,则不会正确匹配。 - brianmearns
@sh1ftst0rm 是的,但这并没有被指定为要求。OP完全有可能希望 ***test**test 匹配,而不是 *test - p.s.w.g
你说得对,它没有明确说明。但是假设从左到右解析,第一次出现的**标记字符串的开头,直到下一个**出现之前的所有内容都是字符串的一部分。就像在C语言中,///A comment被视为 <comment>/A comment</comment>,而不是 <slash /><comment>A comment</comment> - brianmearns
@sh1ftst0rm 我认为 OP 正试图解析类似于 Markdown 的东西,就像你的例子 ***like this** 被解析为 *like this - p.s.w.g
没错,Markdown的工作方式也是一样的:请注意*是加粗内容的一部分。使用您的表达式,星号将在加粗内容之前出现:http://regex101.com/r/fG0iF6 - brianmearns

0

如果您不想使用勉强量词,可以使用这个:

\*\*((?:[^*]|[*](?=[^*]))+)\*\*

解释:这将匹配除了“*”或在一对“**”之间没有跟随“*”的“*”之外的任何字符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接