0

考虑以下标记输入:

* 第 1 行
* 第 2 行
:* 2.1 行
:* 第 2.2 行
* 第 3 行

这通常编码为:

  <ul>
    <li>第 1 行</li>
    <li>第 2 行</li>
    <ul>
      <li>2.1 行</li>
      <li>2.2 行</li>
    </ul>
    <li>第 3 行</li>
  </ul>

我的问题:

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

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

> 1号线 > 2号线 >> 2.1号线 >> 2.2号线 > 3号线

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

行输入格式也可以是:

[第 1 行][第 2 行][第 2.1 行][第 2.2 行]][第 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

4

3 回答 3

3

你的例子对我来说似乎很好。

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

不幸的是,纯正则表达式无法跟踪您所在的嵌套级别,因此它不知道将/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# 语法。

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

于 2009-08-28T23:55:42.617 回答
0

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

我建议以下资源:

于 2009-08-31T18:33:25.673 回答
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>
于 2009-08-31T20:36:22.790 回答