用于维基标记的正则表达式转换

时间:2009-08-28 23:32:25

标签: html regex xhtml wiki user-input

考虑以下标记输入:

* Line 1
* Line 2
:* Line 2.1
:* Line 2.2
* Line 3

这通常编码为:

  <ul>
    <li>Line 1</li>
    <li>Line 2</li>
    <ul>
      <li>Line 2.1</li>
      <li>Line 2.2</li>
    </ul>
    <li>Line 3</li>
  </ul>

我的问题:

  • 使用单行对同一输入的良好表示是什么?
  • 生成相应XHTML的正则表达式是什么?

例如,单行输入格式可以是:

> Line 1 > Line 2 >> Line 2.1 >> Line 2.2 > Line 3

>是无序列表项分隔符。我选择了>,因为文字可能包含典型的标点符号。使用»(或其他此类非104键键)会很有趣,但输入并不容易。

行输入格式也可以是:

[Line 1][Line 2 [Line 2.1][Line 2.2]][Line 3]

更新#1 - 问题稍微简单一些。巢穴的数量可以限制为三个。对于n级深度的一般解决方案仍然很酷。

更新#2 - XHTML,而不是HTML。

更新#3 - 另一种可能的输入格式。

更新#4 - 非常欢迎Java解决方案(或纯正则表达式)。

更新#5

修订代码:

String in = " * Line 1 * Line 2 > * Line 2.1 * Line 2.2 < * Line 3";

String sub = "<ul>" + in.replace( " > ", "<ul>" ) + "</ul>";

sub = sub.replace( " < ", "</ul>" );

sub = sub.replaceAll( "( | >)\\* ([^*<>]*)", "<li>$2</li>" );

System.out.println( "Result: " + sub );

打印以下内容:

Result: <ul><li>Line 1 </li>* Line 2<ul>* Line 2.1<li>Line 2.2</li></ul>* Line 3

3 个答案:

答案 0 :(得分:3)

你的例子对我很好。

 > Line 1 > Line 2 >> Line 2.1 >> Line 2.2 > Line 3

不幸的是,纯粹的RegEx无法跟踪您所处的嵌套级别,因此它不知道将 / UL 关闭标记放在何处。

这样的事可能有用:

 * Line 1 * Line 2 > * Line 2.1 * Line 2.2 < * Line 3

此处,层次结构上下移动大于和小于星号,星号是子弹的分隔符。每个前后的空格都用作一种转义序列,所以你仍然可以按字面意思使用这些字符,或者当它们没有被空格包围时用于斜体和粗体等其他用途。

刺激RegEx:

 string ol = "<ul>" & RegEx.Replace(t, " > ", "<ul>") & "</ul>";
 ol = RegEx.Replace(ol, " < ", "</ul>");
 ol = RegEx.Replace(ol, "( |>)\\* ([^*<>]*)", "<li>\\2</li>"); 

修改:根据下面的评论调整生成XHTML,关闭LI标记。还修复了我的C#语法。

最终编辑:我认为最后一次替换中的\ *和\ 2需要为C#进行转义,修复。另请注意,前两个Replace()调用可以使用String.Replace()而不是RegEx,这可能会更快。

答案 1 :(得分:0)

我不建议使用正则表达式作为解析和转换工具。正则表达式往往具有很高的开销,并且不是解析语言的最有效方法......这就是你真正要求它做的事情。你已经创建了一种简单的语言,你应该这样对待它。我建议为您的WIKI样式格式代码编写一个实际的专用解析器。由于您可以专门针对您的语言定位解析器,因此它应该更有效。此外,您不必创建一些令人恐惧的怪物,这是一个正则表达式来解析您的语言并处理其所有细微差别。从长远来看,您可以获得更清晰的代码,更好的可维护性等优势。

我建议使用以下资源:

答案 2 :(得分:0)

<强>解决方案

工作解决方案如下:

public class Test {
  public Test() {
  }

  public static void main( String[] args ) {
    String in = "= Line 1 = Line 2 > = Line 2.1 = Line 2.2 < = Line 3";

    in = in.replaceAll( "= ([^=<>]*)", "<li>$1</li>" );
    in = in.replace( ">> ", "><ul>" );
    in = in.replace( ">< ", "></ul>" );
    in = "<ul>" + in + "</ul>";
    System.out.println( in );
  }
}

这会创建所需的XHTML片段:

<ul><li>Line 1 </li><li>Line 2 </li><ul><li>Line 2.1 </li><li>Line 2.2 </li></ul><li>Line 3</li></ul>