除非转义,否则在字符串中查找简单模式

时间:2013-06-19 12:48:48

标签: java regex

我有一些代码可以查找简单的粗体标记

private Pattern bold = Pattern.compile("\\*[^\\*]*\\*")

如果有人使用:这是我的*加粗*文本 - 我的模式会找到“粗体”

我现在需要一种方法来使用*而不是在粗体的上下文中。所以我想允许逃避。

E.g。这个我的\ *非粗体\ *文本 - 不应该找到任何模式。

有没有一种简单的方法可以改变我的正则表达式来实现这一目标?

3 个答案:

答案 0 :(得分:5)

你需要一个负面的背后隐藏:

(?<!\\)\*[^*]+(?<!\\)\*

在Java字符串中,这给出了(反斜杠):

"(?<!\\\\)\\*[^*]+(?<!\\\\)\\*"

注意:星号(*)在字符类中没有特殊含义,因此无需转义它

注2:(?<!...)是负面的背后;它是一个锚点,这意味着它找到位置但不消耗任何文本。从字面上看,它可以翻译为:“找到没有前置文本的位置匹配正则表达式...”。其他锚点是:

  • ^:找到之前没有可用输入的位置(即,只能在输入的开头匹配);
  • $:找到之后没有可用输入的位置(即,只能在输入结束时匹配);
  • (?=...):找到以下文字与正则表达式...匹配的位置(这称为正向前瞻);
  • (?!...):找到以下文字匹配正则表达式...的位置(这称为否定前瞻);
  • (?<=...):找到前一个文字与正则表达式...匹配的位置(这是一个积极的外观);
  • \<:找到前面输入为空的位置或不是单词字符的字符,后面的字符是单词字符(取决于实现);
  • \>:找到以下输入为空的位置或不是单词字符的字符,前面的字符是单词字符(取决于实现);
  • \b\<\>

注3:Javascript正则表达式不支持lookbehinds;他们也不支持\<\>。更多信息here

注意4:对于一些正则表达式引擎,可以改变^$的含义来匹配每一行的开头和结尾的位置;在Java中,即Pattern.MULTILINE;在类似Perl的正则表达式引擎中,即/m

答案 1 :(得分:3)

这种基于正面观察的负面正则表达式应该对你有用:

(?<!\\)\*[^*]+\*(?<!\\)

现场演示:http://www.rubular.com/r/sobKUrkTjP

当翻译成Java时,它将成为:

(?<!\\\\)\\*[^*]+\\*(?<!\\\\)

答案 2 :(得分:1)

我认为直到现在这两个答案都非常有趣,但并不完全正确。当粗体文本内部没有星号时,它们不起作用(我认为这几乎是逃避星号的主要原因)。

例如:

  

My * bold \ * text * here,另一个* bold *,more \ *和* here \ *和   \ *结束*更多文字

应该找到三组:

  

* bold \ * text *

     

*粗体*

     

*此处\ *和\ *结束*

通过一些修改,我们可以用这个正则表达式来做到这一点:

(?<!\\)\*([^*\\]|\\\*)+\*

可以在这里测试: http://www.rubular.com/r/Jeml02HHYJ

当然,在Java中需要更多的转义:

(?<!\\\\)\\*([^*\\\\]|\\\\\\*)+\\*