标题

时间:2017-05-22 08:56:27

标签: java html regex markdown stringbuffer

我有一个带有markdown语法的字符串,我希望能够找到标题的markdown语法,即h1 =#,h2 = ## etc etc。

我知道无论什么时候我找到一个标题,它都在行的开头。我也知道每行只能有一个标题。因此,例如,“###这是一个标题”将匹配我的h3模式,但不适用于我的h2或h1模式。到目前为止,这是我的代码:

h1 = Pattern.compile("(?<!\\#)^\\#(\\b)*");
h2 = Pattern.compile("(?<!\\#)^\\#{2}(\\b)*");
h3 = Pattern.compile("(?<!\\#)^\\#{3}(\\b)*");
h4 = Pattern.compile("(?<!\\#)^\\#{4}(\\b)*");
h5 = Pattern.compile("(?<!\\#)^\\#{5}(\\b)*");
h6 = Pattern.compile("(?<!\\#)^\\#{6}(\\b)*");

每当我使用\\#时,我的编译器(IntelliJ)告诉我:“冗余字符转义”。只要我使用\\#,它就会这样做。据我所知,#不应该是正则表达式中的特殊字符,因此使用两个反斜杠转义它应该允许我使用它。

当我找到匹配项时,我希望使用粗体HTML标记来覆盖整个匹配项,例如:“ ### Heading ”,但由于某种原因它无法正常工作

//check for heading 6
Matcher match = h6.matcher(tmp);
StringBuffer sb = new StringBuffer();
while (match.find()) {
    match.appendReplacement(sb, "<b>" + match.group(0) + "</b>");
}
match.appendTail(sb);
tmp = sb.toString();

修改

所以我必须单独查看每个标题,我不能以相同的模式查看标题1-6(这与我使用相同模式的程序的其他部分有关)。到目前为止我所知道的:

  • 如果字符串中有标题,则它位于开头。
  • 如果它以标题开头,则后面的整个字符串将被视为标题,直到用户按Enter键。
  • 如果我有“## This a heading”,那么它必须与h2匹配为true,而对于h1则为false。
  • 当我找到我的比赛时,这个“##这个标题”就变成了这个“ ##这个标题

2 个答案:

答案 0 :(得分:2)

没有必要逃避#,因为它不是一个特殊的正则表达式元字符。此外,^字符串起始锚,因此模式中的所有外观都是多余的,因为它们总是返回 true (因为之前没有字符)一个字符串的开头。)

您似乎希望在单词char之前匹配指定数量的#。使用

String s = "###### Heading6 Something here\r\n" +
           "###### More text \r\n" +
          "###Heading 3 text";
Matcher m = Pattern.compile("(?m)^#{6}(?!#)(.*)").matcher(s);
String result = m.replaceAll("<b>$1</b>");
System.out.println(result);

请参阅Java demo

结果:

<b> Heading6 Something here</b>
<b> More text </b>
###Heading 3 text

<强>详情:

  • (?m) - 现在,^匹配行的开头
  • ^ - 开始行
  • #{6}(?!#) - 正好6 #个符号
  • (.*) - 第1组:0 +字符,而不是换行到行尾。

因此,您的正则表达式定义将类似于

h1 = Pattern.compile("(?m)^#(?!#)(.*)");
h2 = Pattern.compile("(?m)^#{2}(?!#)(.*)");
h3 = Pattern.compile("(?m)^#{3}(?!#)(.*)");
h4 = Pattern.compile("(?m)^#{4}(?!#)(.*)");
h5 = Pattern.compile("(?m)^#{5}(?!#)(.*)");
h6 = Pattern.compile("(?m)^#{6}(?!#)(.*)");

答案 1 :(得分:2)

您可以尝试this

^(#{1,6}\s*[\S]+)

正如你所提到的那样,标题只出现在一行的开头,所以你不需要向后看。

更新: 如果你想加粗以标题开头的整行,你可以试试这个:

^(#{1,6}.*)

并替换为:

<b>$1</b>

Regex Demo

示例Java源代码:

final String regex = "^(#{1,6}\\s*[\\S]+)";
final String string = "#heading 1 \n"
     + "bla bla bla\n"
     + "### heading 3 djdjdj\n"
     + "bla bla bla\n"
     + "## heading 2 bal;kasddfas\n"
     + "fbla bla bla";
final String subst = "<b>$1</b>";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
final String result = matcher.replaceAll(subst);
System.out.println(result);

Run java source