var message = $("textarea").val();
var matches = message.match(/((.*?))/);
if (matches) {
var submatch = message.replace('(' + matches[1] +')', '<div id="'+ matches[1] +'"></div>');
console.log(submatch);
message
变量是一个文本区域,div
是一个带有微笑的CSS图像,在我的聊天应用程序上显示微笑。当我使用"This is (smiley1) and (smiley2)"
时,子匹配变量只显示smiley1,smiley2用括号保持不变;如CCD_ 4。我无法使用包含括号的id
(smiley2(获得此DIV,因为id
没有括号,但我需要括号,因为这是一条包含括号中的微笑的聊天消息。
String#replace
可以通过正则表达式替换,这正是您想要做的。使用g
标志使其成为一个全局正则表达式,可以匹配多个内容。提供一个回调函数可以让你得到每一场比赛的分组。有关详细信息,请参阅MDN。
var message = "This is (smiley1) and (smiley2)";
var result = message.replace(/((.*?))/g, function(match,p1) { return '<div id="'+p1+'"></div>'; });
console.log(result);
作为前传,我想说@Klaycon的答案将是我处理用例的首选方法。虽然我喜欢他们关于如何完成任务的答案,但它并没有解释为什么问题中的代码不起作用的原因;或者如何修改(而不是替换(以使其工作。以下是解决这一问题的尝试
说明
在不使用regex全局标志(即g
(的情况下,.match()
将只提取第一个匹配的响应。所以matches
变量是第一个匹配文本及其捕获组的数组。它看起来像以下内容(请注意,它不包含smiley2的任何内容(:
[ "(smiley1)", "smiley1" ]
有人可能会认为,您可以简单地在正则表达式中添加g
,并获得所有捕获组,但JavaScript不是Perl(或其他可能允许这样做的语言(。RegEx引擎功能强大,但功能有限。相反,您必须使用matchAll()
方法。然而,即使这样也有局限性,因为它返回的是一个可迭代的对象,而不是数组。
因此,一旦有了该对象,就可以从中创建一个数组(例如,使用Array.from
(,其中将包含所有匹配的文本和捕获组。结果看起来像:
[ ["(smiley1)","smiley1"],
["(smiley2)","smiley2"] ]
从那里,您可以迭代matches数组并使用replace()
函数。这就引出了下一点。replace()
的第一个参数可以是字符串或正则表达式。如果它是一个字符串,就像你所说的那样,它只会在它到达的第一个字符串处进行一次性替换。@klayton的答案使用带有全局"g"修饰符的regex来重复。如果你想使用字符串替换,你可以,你只需要迭代你的新匹配数组并多次调用它。
示例(数组(
let message = $("textarea").val();
let re = /((.*?))/g; // global modifier
let matches = Array.from( message.matchAll(re) ); // use matchAll
matches.forEach(match => {
let replace_text = `<div id="${match[1]}"></div>`
message = message.replace(match[0], replace_text)
})
console.log(message)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea>
This is (smiley1) and (smiley2)
</textarea>
示例(可迭代对象(
当然,因为matchAll()
返回一个可迭代的对象;您不需要将其转换为数组。您可以使用适当的循环机制对其进行迭代。以下使用for..of
:
let message = $("textarea").val();
let re = /((.*?))/g; // global modifier
let matches = message.matchAll(re); // use matchAll
for (let match of matches){
let replace_text = `<div id="${match[1]}"></div>`
message = message.replace(match[0], replace_text)
}
console.log(message)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea>
This is (smiley1) and (smiley2)
</textarea>
最后备注
最后一点值得注意的是,您正在用具有id
的元素替换文本。这打开了您的页面,您可能会有许多具有相同id
值的元素;它会变成无效的HTML,但会让您遇到其他不可预见的问题(例如,JavaScript事件处理(。为此,我建议使用class属性(例如class="smiley1"
(。