帮助 javascript 正则表达式向某些字符添加反斜杠(如果尚不存在)

发布于 2024-10-19 18:58:29 字数 1508 浏览 1 评论 0原文

我有另一个 Javascript 正则表达式难题...(抱歉,如果这有点啰嗦 - 很难解释!)

我有一个脚本,它将一个字符串发送到弹出窗口(所有字符在发送时都会被编码,因此所有反斜杠被保留)。在弹出窗口中,它有几个文本输入框,还有一个“摘要”范围,显示所有输入框中的内容,并在检测到按键时更新。然后,当用户完成后,他们单击一个按钮,将更新的摘要字符串发送回开启者。

要求是反斜杠自动添加到以下字符之前:\ / },因此用户不需要自己执行此操作。目前,我的代码可以删除输入框中的所有反斜杠,但摘要会在适当的地方添加它们。

例如。如果将此字符串发送到弹出窗口:foobar\\batz\/hi 然后,在摘要中将如下所示:foobar\\batz\/hi,在输入框中将如下所示:foobar\batz/hi。 如果您随后在输入框中编辑如下字符串:foobar\batz/hiya,则摘要中的内容如下所示:foobar\\batz\/hiya。 到目前为止一切顺利...但是如果您尝试在输入框中键入:foobar\\batz/hiya,那么它在摘要中看起来像这样:foobar\\\batz \/嗨。 它应该如下所示: foobar\\\\batz\/hiya

这取决于现有代码(在每个“kepup”上运行)。它基本上需要一个正则表达式来查看字符串,并在 \ / 或 } 中添加反斜杠(如果它们尚不存在)。这需要负向后查找来检查预先存在的反斜杠(但 javascript 不能执行负向后查找)。我以为我已经通过首先反转字符串(使用自定义函数)并进行负向查找,然后再次反转字符串来解决此问题,如下所示:

var thisBoxVal = $(this).val();
thisBoxVal = reverseStr(thisBoxVal);
thisBoxVal = thisBoxVal.replace(/(\}|\/|\\(?!\\))/g,"$1\\");
thisBoxVal = reverseStr(thisBoxVal);

但是,我现在可以看到问题所在。当遇到第一个(或第二个,因为它是相反的)双反斜杠时,它会添加额外的反斜杠。但因为第二个反斜杠已经有第一个反斜杠,所以它不会添加它。

我还担心每次字符串反转时的内存分配。这是因为我了解到 javascript 字符串是不可变的,我相信这会产生不幸的效果,即每次字符串反转时都会分配更多内存。在每次击键时执行此操作(因为每当输入框发生更改时都需要执行此操作以更新摘要行)可能会导致一些问题(...?)。

还有其他方法可以做到这一点吗?最好只使用一些正则表达式,并且没有反转...

总而言之,要求是创建一个正则表达式替换,在字符串中搜索任何这些字符 \ / } 并添加“转义”反斜杠在它们之前(如果转义反斜杠尚不存在)。因此,当连续遇到多个反斜杠时,它应该具有智能,以转义每个反斜杠(请注意,我没有更新实际的输入框,而是更新摘要的变量)。

我需要正则表达式大师的帮助!

I have another Javascript regex conundrum... (apologies if this is a bit long-winded - hard to explain!)

I have a script which sends a string to a popup window (all characters are encoded when they are sent, so all backslashes are preserved). In the popup it has several text input boxes, and also a 'summary' span which displays what is in all the input boxes, and is updated whenever a keyup is detected. Then when the user is finished, they click a button which sends the updated summary string back to the opener.

The requirement is that backslashes are prepended automatically to the following characters: \ / }, so the user doesn't need to do this themselves. Currently I have code that strips out any backslashes in the input boxes, but the summary adds them where appropriate.

Eg. if this string is sent to the popup: foobar\\batz\/hi
Then it will look like this in the summary: foobar\\batz\/hi and like this in the input box: foobar\batz/hi.
If you then edit the string like this in the input box: foobar\batz/hiya, then it looks like this in the summary: foobar\\batz\/hiya.
So far so good... but if you attempt to type this in the input box: foobar\\batz/hiya, then it looks like this in the summary: foobar\\\batz\/hiya.
It should look like this: foobar\\\\batz\/hiya

This is down to the existing code (that is run on every 'kepup'). It basically needs a regex to look at the string, and add backslashes to \ / or } if they do not exist already. This requires a negative lookbehind to check for pre-existing backslashes (but javascript cannot do negative lookbehinds). I thought I had cracked this by reversing the string first (using a custom function), and doing a negative lookahead, then reversing the string again, like this:

var thisBoxVal = $(this).val();
thisBoxVal = reverseStr(thisBoxVal);
thisBoxVal = thisBoxVal.replace(/(\}|\/|\\(?!\\))/g,"$1\\");
thisBoxVal = reverseStr(thisBoxVal);

However, I can now see where the problem lies. When encountering the first (or 2nd because it is reversed) of a double backslash, it adds the extra backslash. But because the 2nd backslash has this first backslash there already, it won't add it.

I also have concerns about memory allocation every time a string is reversed. This is because I learned that javascript strings are immutable, which I believe has the unfortunate effect of allocating more memory every time a string is reversed. Doing this on every keystroke (as it needs to do this to update the summary line whenever the input box is altered) may cause some issues(...?).

Is there any other way of doing this? Preferably with just some regex, and no reversing...

So to summarise, the requirement is to create a regex replace that searches a string for any of these chars \ / } and add an 'escaping' backslash before them (if an escaping backslash doesn't exist already). So it should have the intelligence when encountering more than one backslash in a row, to escape each one (note that I'm not updating the actual input box, but a variable which I use to update the summary).

I need a regex master's help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

剧终人散尽 2024-10-26 18:58:29

您可以转义任何字母、数字、空格或反斜杠的内容。

string=string.replace(/([^\w \\])/g,'\\$1')

You could escape anything that is not a letter, digit, space or backslash.

string=string.replace(/([^\w \\])/g,'\\$1')
蝶…霜飞 2024-10-26 18:58:29

以下应该可以解决这个问题:

thisBoxVal = thisBoxVal.replace/((\}|\/(?!\\))|\\)/g,"$1\\");

但是这个要求似乎很奇怪。为什么\\要翻译成\\\\,而\{要翻译成\{。这也意味着如果字符串 foo\\{bar 在摘要中,则在输入框中它是 foo\{bar,当您再次保存时,它会变成摘要中的foo\{bar。这听起来像是一个错误。如果我是你,我就会完全放弃负面的展望。

The following should solve it:

thisBoxVal = thisBoxVal.replace/((\}|\/(?!\\))|\\)/g,"$1\\");

But the requirement seems strange. Why should \\ translate into \\\\, but \{ into \{. This also means if the string foo\\{bar is in the summary, it is foo\{bar in the input box, and when you save that again, it becomes foo\{bar in the summary. That sounds like an error. If I were you I'd just drop the negative lookahead altogether..

骷髅 2024-10-26 18:58:29

您可以通过检查要转义的字符之前是否有偶数个反斜杠来检查现有的反斜杠转义,在这种情况下,需要额外的反斜杠:

thisBoxVal = thisBoxVal.replace(/(^|[^\\])((?:\\{2})*)(\\(?=[^\\/}]|$)|[/}])/g, '$1$2\\$3');

正则表达式分解如下:

  • (^|[^\\])< /code>:在转义之前,匹配不是转义的内容(字符串开头或非 \)
  • ((?:\\{2})*):偶数转义字符。在每一对中,第一个逃脱了第二个,所以我们不想碰它们。
  • (\\(?=[^\\/}]|$)|[/}]):要转义的字符:
    • \\(?=[^\\/}]|$):反斜杠,后跟不可转义的字符,该字符可以是不可转义的字符(< code>[^\\/}],否则这个反斜杠本身就会转义后面的字符)或字符串结尾。
    • [/}]:可转义字符,反斜杠除外。

示例字符串:

thisBoxVal = "sl0: \\;  sl1: /;  sl2: \\\\\\;  nosl0: \\\\;  nosl1: \\{;  sl3: \\";

打印值:"sl0: \; sl1: /; sl2: \\\; nosl0: \\; nosl1: \{; sl3: \"
替换的结果:"sl0: \\; sl1: \/; sl2: \\\\; nosl0: \\; nosl1: \{; sl3: \\"

You can check for existing backslash escapes by checking for an even number of backslashes before the characters to escape, in which case an additional backslash is needed:

thisBoxVal = thisBoxVal.replace(/(^|[^\\])((?:\\{2})*)(\\(?=[^\\/}]|$)|[/}])/g, '$1$2\\$3');

The regexp breaks down as follows:

  • (^|[^\\]): before the escapes, match something that isn't an escape (start-of-string or non-\)
  • ((?:\\{2})*): an even number of escape characters. In each pair, the first escapes the second, so we don't want to touch these.
  • (\\(?=[^\\/}]|$)|[/}]): the character to escape:
    • \\(?=[^\\/}]|$): a backslash, followed by something that isn't escapable, which is either a character that isn't escapable ([^\\/}], otherwise this backslash would itself be escaping the character that follows) or the end-of-string.
    • [/}]: an escapable character, other than an backslash.

Sample string:

thisBoxVal = "sl0: \\;  sl1: /;  sl2: \\\\\\;  nosl0: \\\\;  nosl1: \\{;  sl3: \\";

Print value: "sl0: \; sl1: /; sl2: \\\; nosl0: \\; nosl1: \{; sl3: \"
Result of replace: "sl0: \\; sl1: \/; sl2: \\\\; nosl0: \\; nosl1: \{; sl3: \\"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文