我有以下文字:
嗨,我打电话是想请你 -b-please- 带 -b-kids- 去 -b-school-
我怎样才能用 Javascript 捕捉里面的文本-b- ... -等等,不管是否有粘贴文本,例如:hello-b-Sofia-
只是里面的东西。好吧,我想将该文本设为粗体、斜体或删除线。
就像是:
你好,我打电话是想请你送孩子上学。
我找到了一个有效的正则表达式,但它只在 PHP 中有效,我对正则表达式了解不多。
好吧,考虑到 -b-... 中允许使用连字符 - 我想知道哪种方法更有洞察力或更有效,但是,当然要解释原因。我想知道在什么情况下indexOf更好,还有哪些RegExp
关于马里亚诺的回应
正则表达式效果很好,尽管它仅在内容中没有连字符时才有效。 从fav-or 中可以看出。
我认为这个正则表达式比它通常看起来更复杂。作为一个字符串:“我使用很多 --- 因为 - 我是 - 叛逆的 -.-。”
那么它将是:
-b-我使用很多 --- 因为 - 我是 - 叛逆 -.-.-
现在,应该有一条规则,它应该始终在另一个-b-之前查找最后一个存在的连字符;不是第一个,根据给定的正则表达式,匹配第一个匹配项。
之后,如果未找到“最后一个”,则没有匹配项,因此保留正常文本。感谢您成为西部最快的牛仔:v
关于蒙托罗的回答
有时或可能一直“让生活变得更复杂”听起来很棒,因为我通常会发现所有事情都有问题。
indexOf解决方案的执行速度比RegExp快,尽管在代码处理方面它有点复杂。我不明白一些-1的使用(我不太明白)。这听起来很疯狂,但即使在内部使用连字符,它也确实有效。
大声笑,我通常使用 JQuery :)
它可以
replace( regexp, reemplazo)
与以下正则表达式一起使用:并将其替换为
<b>$1</b>
描述:
-b-
- 匹配文字文本。([^-]+)
第 1 组 - 比赛:[^-]+
- 1 个或多个不是连字符 (-
) 的字符。-
- 匹配文字文本g
- 查找所有匹配项,而不仅仅是第一个匹配项。第 1 组除了匹配连字符之间的文本外,还会创建一个陷阱。替换时,
$1
包含该捕获的值。避免使用语法中的 HTML 标记:
此外,在使用的语法中
-b-
……-
不应该有 HTML 标签,以免“破坏”结构。<
一种可能的解决方法是使用正则表达式匹配没有任何 的结构:这些表达式中的任何一个都适用于任何类似 Perl 的正则表达式方言,因此它们将适用于 JavaScript、PHP 或任何其他常用语言。
在语法中包含连字符:
如果我们想让它更复杂一点:我们将如何允许在粗体文本中使用连字符?我们可以要求他们逃脱惩罚
\
。在这种情况下,我们将使用:此结构使用称为展开循环的技术,将 la
\
内的不允许字符作为正常字符,然后匹配斜线后跟任何字符 (\\.
) 和更正常的字符。结束代码:
已编辑问题的答案:
我不会回答一般性问题,因为它基于意见,但我会将其与@AlvaroMontoro 的答案进行比较,这非常好,我建议给它 +1 票。值得澄清的是,提议的实现寻求不同的结果(我们将梨与香蕉进行比较,见下文)。
如果我们进行一般比较,对于使用的示例,观察到大约 9%(大约 6μs)的差异,我认为这与 JavaScript 无关。然而,这一切都取决于被比较的文本。例如,如果我们采用更长的文本(6 段),我们可以获得大约两倍于正则表达式的结果(在JSPerf中的比较)。并且可能也可以将测试定向到有益的文本
lastIndexOf()
。这是不正确的。正如本答案中所讨论的,为了在语法中允许使用连字符,它们必须使用反斜杠 (
\
) 进行转义。Demo en regex101.com
为什么我认为搜索最后出现的连字符不方便?我认为查找最后一次出现是一个错误的决定,因为它不允许有效地关闭语法。让我们考虑这个例子:
如果这是 SO 帖子中使用的语法,我们将无法在最后一个粗体之后使用连字符,我们将无法关闭它们。如果它用于用户输入的文本,我不知道如何记录使用。相反,我认为要求它逃避它们更有效(并且更常用)
"-b-por fav\-or-"
。但是,如果您仍然希望匹配最后一次出现,我会要求在问题中澄清如何在最后一个粗体之后使用连字符。
这是一个神话,即较长的正则表达式效率较低,您多次听到它,但它仍然是错误的,而且很多时候恰恰相反。事实上,所使用的技术非常普遍,您可以在以下位置阅读更多详细信息:
注意:我本可以更简略地呈现它,
/-b-(([^-\\]|\\.)*)-/g
但我更喜欢合并一个更高效、质量更高的版本(这里越长越高效)。它基本上包括使用:
其中normal是除
-
,\
和之外的所有字符<
,而special是前面带有反斜杠的任何字符,以匹配\-
。机制:
[^-<\\]*
,\\.
然后是更正常的字符
[^-<\\]*
我不是故意的 :-) 我相信质量高于一切。
我知道这个问题需要正则表达式,并且使用它们会大大简化你的生活(Mariano 的解决方案非常优雅,几乎不占一行)......但有时我喜欢让我的生活复杂化:P
正则表达式功能强大且灵活……但这也使它们变得缓慢。如果你正在寻找一个特定的字符串,
indexOf
它也可以工作。基于此,我制作了一个小算法,在循环内按顺序排列:-b-
并将其替换为<b>
-
并将其替换为</b>
代码不像 Mariano 的解决方案那样漂亮或干净,但是使用 JSPerf 进行测试,它的性能似乎是可比的。
这将是代码:
编辑:马里亚诺告诉我,如果链条没有正确关闭(如果
-b-
没有-
之后),代码就会出现问题......他是对的。所以我稍微更改了代码,以便进行额外的检查以避免无限循环。结果如下所示:
假设如果你留下了
-b-
没有结束的 a,那么它是粗体的,直到句子的结尾。JSPerf中的结果似乎仍然具有可比性。Máxima Alekz正确地评论说我的代码不允许内部连字符。如果您允许它们,一种解决方法是向后而不是向前遍历链。要做到这一点而不是使用
indexOf
,我们将使用lastIndexOf
。该算法现在所做的是找到
-b-
链中的最后一个并将其链接到-
之后找到的最后一个。如果没有找到连字符,则字符串的结尾被认为是粗体的结尾。代码如下所示:
这里是JSPerf中的结果,仍然与上面的结果相似。