【问题标题】:jquery, parse partial text input to formatted html output?jquery,将部分文本输入解析为格式化的html输出?
【发布时间】:2012-10-14 00:33:28
【问题描述】:

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

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

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

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

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

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

show(startsWith("-"));

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

在图片中,可以看到绿色为comments,白色为input,黑色为output

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

【问题讨论】:

    标签: jquery regex parsing input textarea


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

    this 是您要查找的内容吗?它并不完美,但它具备基本功能。

    它的工作原理如下:

    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>)
    

    【讨论】:

    • 谢谢。解释很清楚。正则表达式对于新程序员来说一直是一个非常麻烦的话题,我想,所以我希望每个人都阅读你的答案。
    • 你正在使用console.log,而他使用了keyup 函数。有什么区别?
    • 其实我也用过key up功能(见html)。 console.log 是在我调试它时使用的。忽略它。
    • 实际上,我看不到更改已提交给您的 JS 小提琴;否则,感谢您对正则表达式的解释。
    • jsfiddle.net/Ns9eL/3 - 但我唯一做的就是删除console.log。如果您查看 html,您会看到 textarea 有一个 onkeyup 函数。
    【解决方案2】:

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

    我做了两次替换,第一次添加&lt;ul&gt;&lt;/ul&gt;,然后添加&lt;li&gt;&lt;/li&gt;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 中捕获的列表项 包含在&lt;ul&gt;&lt;/ul&gt; 标签中:

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

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

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

    一句话,

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

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

    【讨论】:

    • 这绝对是一个好的开始。我正在尝试用我的其他代码来编排它,现在可以在这里看到:jsfiddle.net/5ZXnx。我还不能做到这一点,但我可以看到有很强的重叠。当我想到 jquery 时,我总是会想到“即时”/“不刷新”/“预览”,你知道吗?我会在一两个小时后回来告诉你我是否能够适应它。
    • @Wolfpack'08 - 嗯,你可能看到了我原来的版本,我使用了change事件,但是如果你刷新,最新版本使用keyup,所以有即时更新键入时。另外,我注意到每个表达式中的第二对\s* 引起的错误;它们必须替换为[\t ]
    • 哦,好点。是的,你有这个想法。不过,我想不出一种优雅的方式来整合它。查看已编辑的解决方案...
    • @Wolfpack'08 - 添加了说明。不过,要回答您的问题,我需要一组来封装“一个或多个{列表项}”,即(...)+,以及一组封装“字符串开头或换行符”,即(^|[\n\r]+),因为我不需要它们被捕获(即进入$2$3),我将它们设为不可捕获。我本可以让它们被捕获;没关系。我只是想明确地将我不使用的任何组设为不可捕获。
    • @Wolfpack'08 - 看看新的眼睛如何看待事物总是很有趣!您似乎将?: 视为某种“非”,因此您将?:?: 视为“非非”。相反,将(?: ... ) 视为一种完全不同的括号,与( ... ) 分开。为什么语言设计者选择(?: ... ),我不确定。至于\n,不,没用;我添加了\ns,所以&lt;pre&gt;&lt;/pre&gt; 中的输出在jsFiddle 中看起来不错。
    【解决方案3】:

    你死心塌地使用正则表达式有什么原因吗?虽然它们很好,因为它们高效且简洁,但如果我稍后再返回它们,我经常会发现它们很难阅读。

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

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

    而不是:

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

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

    Example in JsFiddle(感谢 FrankieTheKneeMan 为 ul 提供的 css)

    【讨论】:

    • 另外,当你使用&lt;ul&gt;&lt;li&gt;item 1&lt;/li&gt;&lt;/ul&gt; &lt;ul&gt;&lt;li&gt;item 2&lt;/li&gt;&lt;/ul&gt;时,目标是xpath和这样的变化
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    相关资源
    最近更新 更多