3

我正在查看非常少量的代码:

var val = $("#id_input").val();
$("#output").text(val);

它本质上将输入输入到一个字段中<textarea id="id_input"></textarea>,并按原样输出。

我正在尝试做的是将以 a 开头的输入换行符转换为我网站上的-输出<ul><li></li></ul>....

我一直在采用的方法是按行拆分输入,然后将它们连接起来,在将每一行通过这个之后:

function startsWith(string, pattern) {
  return string.slice(0, pattern.length) == pattern;
}

show(startsWith("-"));

我觉得有一个更标准的方法吗?例如,我在 StackOverflow 上阅读了其他使用find函数产生类似结果的帖子。我怀疑这些,因为没有实际的正则表达式。这似乎好得令人难以置信。

在此处输入图像描述

在图像中,您可以看到绿色文本是comments,白色文本是input,黑色文本是output

我了解现有技术具有此功能,但它们具有许多其他功能。我正在尝试创建一个隔离此功能的输入。

4

3 回答 3

5
uls = val.replace(/(^-.*$(?:\n^-.*$)*)/mg, "<ul>\n$1\n</ul>")
lis = uls.replace(/^-(.*)$/mg, '<li>$1</li>')
$("#output").html(val);

这是要找的吗?它并不完美,但它具有基础知识。

它的工作原理如下:

Surround the would be lists with <ul></ul>
    This works by finding lines that start with a '-' |^-.*$|,
    then matching contiguous, similar lines |(?:\n^-.*$)| 0 or more times |*|
    it uses the multiline (m) and global (g) flags too:
      match ^ and $ at the begining and end of lines (m)
      and get all the ones in the string (g)
    surround them (<ul>\n$1\n</ul>)
Surround the list items with <li></li>
     match lines with a hyphen at the beginning |^-(.*)$|
     surround them (<li>$1</li>)
于 2012-10-24T01:09:14.057 回答
1

这是您可以自己调整的开始:jsFiddle

我做了两次替换,首先添加<ul></ul>,然后添加<li></li>s。(如果 JavaScript 支持后向断言,一步完成会更容易;没有它们,它仍然是可能的,但会很麻烦。)

    val = val.replace(/((?:(?:^|[\n\r]+)[\t ]*-[\t ]*[^\n\r]*)+)/g, "\n<ul>\n$1\n</ul>");
    val = val.replace(/[\n\r]+[\t ]*-[\t ]*([^\n\r]*)/g, "\n  <li>$1</li>");

我在构建它时做了一些假设,您可能必须撤消这些假设:

  1. 将一系列换行符视为一个换行符。
  2. 删除前后的空格和制表符-

以下输入,

hello, world.
- two
- things
hi, again.
- three
 -more 
-things

创建以下输出:

hello, world.
<ul>
  <li>two</li>
  <li>things</li>
</ul>
hi, again.
<ul>
  <li>three</li>
  <li>more </li>
  <li>things</li>
</ul>

解释

第一个正则表达式只是标识一列表项。

(                   Captured group ($1).

    (?:             Group (one list item). -------------------+
                                                              |
        (?:         Group (for alternation). ---------+       |
                                                      |       |
            ^       Start-of-string                   |       |
                                                      |       |
            |           OR                      <-----+       |
                                                              |
            [\n\r]+     one or more newlines.                 |
                                                              |
        )                                                     |
                                                              |
        [\t ]*      (Ignore tabs and spaces.)                 |
        -           (Dash.)                                   |
        [\t ]*      (Ignore tabs and spaces.)                 |
                                                              |
        [^\n\r]*    List item text (everything but newlines). |
                                                              |
    )                                                         |
    +               One or more list items. <-----------------+

)

捕获的这列表项$1包含在<ul></ul>标签中:

"\n<ul>\n$1\n</ul>"

第二个正则表达式将每个列表项包装在<li></li>标签中,并且与第一个非常相似,因此显示更改的内容可能更有用:

first regex  : /((?:(?:^|[\n\r]+)[\t ]*-[\t ]* [^\n\r]* )+)/g
differences  :  xxxxxxxxx       x             (        )xxx
second regex : /         [\n\r]+ [\t ]*-[\t ]*([^\n\r]*)   /g

言下之意,

  1. 我们不再关心列表项的集合,只关心每个列表项,因此我们可以删除用于量化的不可捕获组(?:...)+,,

  2. 在第一次正则表达式替换之后(在 a 前面\n<ul>\n),列表项应该不可能从字符串的开头开始,所以我们可以删除交替(?:^|...),,

  3. 但是我们现在对捕获列表项文本感兴趣,因此我们添加了一个捕获组(...).

于 2012-10-24T01:05:37.317 回答
1

您是否有理由坚持使用正则表达式?尽管它们很好,因为它们高效且简洁,但如果我稍后再返回它们,我经常会发现它们很难阅读。

我可能会以与您相同的方式解决问题,只是我会将每个列表项包装在自己的列表中以处理子列表:

<ul><li>item 1</li></ul>
<ul><li>item 2</li></ul>

而不是:

<ul>
<li>item 1</li>
<li>item 2</li>
</ul>

它优雅地处理列表和非列表项的混合。我不会使用这种方法的唯一原因是如果我以后必须一起操作列表中的所有内容(例如 - 设置第一个列表的样式,而不是第二个列表)。

JsFiddle 中的示例(感谢 FrankieTheKneeMan 为 ul 提供的 css)

于 2012-10-24T02:34:11.663 回答