jquery,将部分文本输入解析为格式化的html输出?

Posted

技术标签:

【中文标题】jquery,将部分文本输入解析为格式化的html输出?【英文标题】:jquery, parse partial text input to formatted html output? 【发布时间】: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("-"));

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

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

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

【问题讨论】:

【参考方案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>");

我在构建这个时做了一些假设,您可能需要撤消这些假设:

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

以下输入,

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

一句话,

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

    1234563 p>

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

【讨论】:

这绝对是一个好的开始。我正在尝试用我的其他代码来编排它,现在可以在这里看到: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和这样的变化

以上是关于jquery,将部分文本输入解析为格式化的html输出?的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 将 Html 转换为文本并返回

使用 XSLT 2.0/3.0 使用多个步骤将 CDATA 中的纯文本解析为 html。那里的一部分

使用 jQuery 或纯 Javascript 访问一组 HTML 输入文本框

jQuery文本框输入格式限制valueChange replace光标移动问题

Jquery怎样实现文本输入框鼠标定位时弹出提示

验证:验证邮箱格式是否正确