Java正则表达式解析任意数量的Markdown样式链接

时间:2014-05-14 14:29:22

标签: java regex markdown

我正在尝试为任何出现的降价风格链接解析字符串,即[text](link)。我能够获得字符串中的第一个链接,但如果我有多个链接,则无法访问其余链接。这是我尝试过的,你可以在ideone上运行它:

Pattern p;
try {
    p = Pattern.compile("[^\\[]*\\[(?<text>[^\\]]*)\\]\\((?<link>[^\\)]*)\\)(?:.*)");
} catch (PatternSyntaxException ex) {
    System.out.println(ex);
    throw(ex);
}
Matcher m1 = p.matcher("Hello");
Matcher m2 = p.matcher("Hello [world](ladies)");
Matcher m3 = p.matcher("Well, [this](that) has [two](too many) keys.");
System.out.println("m1 matches: " + m1.matches());  // false
System.out.println("m2 matches: " + m2.matches());  // true
System.out.println("m3 matches: " + m3.matches());  // true
System.out.println("m2 text: " + m2.group("text")); // world
System.out.println("m2 link: " + m2.group("link")); // ladies
System.out.println("m3 text: " + m3.group("text")); // this
System.out.println("m3 link: " + m3.group("link")); // that
System.out.println("m3 end: " + m3.end());          // 44 - I want 18
System.out.println("m3 count: " + m3.groupCount()); // 2 - I want 4
System.out.println("m3 find: " + m3.find());        // false - I want true

我知道我不能拥有repeating groups,但我认为find会起作用,但它不会像我预期的那样起作用。如何修改我的方法以便我可以解析每个链接?

2 个答案:

答案 0 :(得分:1)

你不能逐个完成比赛并在上一场比赛后从一个索引进行下一场比赛吗?你可以使用这个正则表达式:

\[(?<text>[^\]]*)\]\((?<link>[^\)]*)\)

即使匹配是整个字符串的子字符串,方法Find()也会尝试查找所有匹配项。每次调用都会获得下一场比赛。 Matches()尝试匹配整个字符串,如果不匹配则失败。使用这样的东西:

while (m.find()) {
    String s = m.group(1);
    // s now contains "BAR"
}

答案 1 :(得分:0)

我用来匹配你需要的正则表达式(没有组)是\[\w+\]\(.+\)

这只是为了向您展示它。基本上它确实:

  • 过滤方格:\[
  • 后跟任何单词char(至少1):\w+
  • 然后是方格:\]

这将寻找这些模式[blabla]

然后用括号表示......

  • 过滤括号:\(
  • 跟随任何字符(至少1):.+
  • 然后括号:\)

所以它过滤了(ble...ble...)

现在,如果要将匹配项存储在组中,可以使用其他括号,如下所示:

以这种方式

(\[\w+\])(\(.+\))您可以存储单词和链接。

希望能提供帮助。

我已经尝试过regexplanet.com并且它正在运行

更新:解决方法.*(\[\w+\])(\(.+\))*.*