正则表达式:匹配简单的Markdown格式

5
我正在尝试找出正则表达式以匹配所有出现的*这种字符串*。不幸的是,另外两个规则使得这件事情比我想象的更加复杂:
  1. 标记的字符串应该以*开头,后面跟着非空格字符(所以* this one*不应该被匹配)
  2. 标记的字符串应该以非空白字符结尾,后面跟着*然后是空格(所以*this one **this o*ne不应该被匹配)
我从最简单的正则表达式\*\S([^\*]+)?\*开始,对于我的测试字符串: *foo 1 * 2 bar* foo *b* azz *qu **ux* 匹配如下位置: [*foo 1 *] 2 bar* foo [*b*] azz [*qu *][*ux*] 这是我想要实现的: [*foo 1 * 2 bar*] foo [*b*] azz [*qu **ux*] 所以出现了两个问题:
  • 如何在正则表达式中表达第2条规则:“搜索直到出现第一个非空白字符,后面跟着*,然后是空格”?使用肯定的前瞻吗?
  • 如何匹配第2条规则中的空格,但不将其包含在结果中,\*\S([^\*]+)?\*\s会这样做吗?

请说明类似于 *1**2*****1* 的输入字符串应该如何处理? - revo
[*1**2*] as 2* is the first closing one in the string following the rule of "non-whitespace followed by * followed by whitespace". Same for second example: [****1*] - Michal
所以你想完全匹配吗? - revo
是的,这两种情况应该完全匹配。 - Michal
*****foo 1 * 2 bar*的预期结果是什么?整个字符串还是*foo 1 * 2 bar* - Wiktor Stribiżew
我更新了我的答案以支持两种情况。 - Wiktor Stribiżew
4个回答

2
如果你想从*最右边开始匹配,你可以使用"最初的回答"。
\*(?=[^\s*]).*?(?<=[^\s*])\*(?!\S)

要从最左侧的*(如``)开始匹配,请从第一个环视中删除*(或将其模式替换为\S):

最初的回答:

要从左边第一个星号(如 ``)开始匹配,请从第一个环视中删除星号(或用 \S 替换它的模式):

\*(?=\S).*?(?<=[^\s*])\*(?!\S)

请看正则表达式演示 #1正则表达式演示 #2。在开头添加(?s)或使用Pattern.DOTALL进行编译,以匹配跨行的文本。

细节

  • \* - 一个*字符
  • (?=[^\s*]) - 下一个字符必须是非空格且不是*
  • .*? - 尽可能少的任意0个或多个字符
  • (?<=[^\s*]) - 前面的字符应该是非空格且不是*
  • \* - 一个*字符
  • (?!\S) - 空格边界模式,下一个字符可以是空格,或者字符串结束位置在此处。

在Java中:

String regex = "\\*(?=[^\\s*]).*?(?<=[^\\s*])\\*(?!\\S)";

1
您可以使用 this 正则表达式:
\*(?!\s)(.*?)(?<!\s|\*)\*(?=\s|$)

如何在正则表达式中表达规则2中的"查找到第一个非空格后跟随*后跟空格出现"?使用正向先行断言?

您可以使用负向回顾后发现仅匹配最终星号,只有在它之前有非空格字符和正向先行查找来匹配星号,当它后面是空格字符或字符串的结尾时进行匹配。

如何匹配规则2中的空格,但不将其包含在结果中,*\S([^*]+)?*\s能做到吗?

如果您想检查pattern是否在不消耗它的情况下后面跟着一个字符,您可以使用先行断言,例如pattern(?=\s)不会消耗\s,而pattern\s会消耗。


0

我使用了完全匹配而不是组匹配,它完美地匹配了你的测试字符串:

"(?<=\\s|^)\\*(?:\\S|\\S.*?\\S)\\*(?=\\s)"

0
public class Test {

    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("\\*\\S.*?(?<!\\s)\\*(?=\\s|$)");
        Matcher matcher = pattern.matcher("*foo 1 * 2 bar* foo *b* azz *qu **ux*");
        int i = 1;
        while(matcher.find()) {
            System.out.printf("%d: %s%n", i++, matcher.group());
        }
    }
}

*\S : *后面跟非空白字符

.*? : 非贪婪地消耗字符。

(?<!\s)* : *跟随非空白字符。这是负向预测,不会消耗非空白字符。

(?=\s|$) : 正向预测。*应该后跟空格或行尾。


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