如何在正则表达式中添加JavaScript中匹配的一系列字符的反勾号

How do I add a backtick to a regex on a range of characters matching in JavaScript?

本文关键字:字符 一系列 正则表达式 添加 JavaScript      更新时间:2023-09-26

想象一下我有字符串

asdf-'`

我想使用正则表达式验证它是否正常。

即字母、连字符、撇号和反号。

除了以下示例中的倒勾外,其他一切都正常工作:

html:

Type something here: <input type="text" id="in">
<div id="out"></div>

javascript:

var $out = $("#out");
$("input").keyup(function () {
    if (/^[a-zA-Z ' -`]+$/.test(this.value))
        $out.text("Regex tested OK");
    else
        $out.text("Regex tested not OK");
});

结果:

Type something here: asdf-'`
Regex tested not OK

我的问题是:如何在JavaScript中匹配的一系列字符的正则表达式中添加反勾号(backticks上的其他regex问题似乎没有解决这个问题)。

您的答案

首先,正则表达式确实有效,只是与您的想法不同我稍后再讨论,根据下面的水平规则

问题不在于后勾号,而在于前连字符。由于使用连字符创建(a-z)(A-Z)范围,因此必须注意,连字符可以是"字符类"(方括号中包含的字符的名称)中的特殊字符,以创建两个有效字符之间的范围。但是,最后三个字符也会在空格和反调( -`)之间创建一个范围,而不是显式搜索连字符和反调。

因此,如果你想专门查找连字符,你需要执行以下操作之一:

  1. 不要把它放在两个有效字符之间。这意味着,将它放在开始、结束、另一个范围之后,等等
  2. 逃离它

下面是一些例子,以及一个固定的jsfiddle(http://jsfiddle.net/a4vGA/63/):

// Personally, I like #2. Escaping the hyphen just reads much nicer to me:
/^[a-zA-Z' '-`]+$/  // The searchable hyphen char is escaped, breaking the range.
// But any of these all make the searchable hyphen work without escaping:
/^[a-zA-Z' `-]+$/  // The searchable hyphen char is last
/^[-a-zA-Z' `]+$/  // The searchable hyphen char is first
/^[a-z-A-Z' `]+$/  // The searchable hyphen char is between two ranges and, 
                   // therefore, cannot create a range
/^[a-zA-Z-' `]+$/  // The searchable hyphen char is after a range and and, 
                   // therefore, cannot create a range
// etc.

以上任何一项都将回答您的问题。你可以在这里停止阅读


为什么它以前有效

您的问题很有趣,因为问题中粘贴的正则表达式实际上与粘贴的字符串asdf-'`一起工作

/^[a-zA-Z ' -`]+$/.test("asdf-'`") // true; but not why you may think.

注意:您的评论中的jsfiddle只是在问题中粘贴的正则表达式中出现了一个拼写错误,意外地省略了导致它与测试字符串一起失败的反勾号。)

那么,正如我们上面所讨论的,如果这个表达式的连字符创建了三组范围,而没有显式搜索连字符,为什么它仍然有效?让我们把这个表达式分解一下,看看发生了什么。

粘贴的表达式^[a-zA-Z ' -`]+$将匹配从行首到行尾的任何一系列匹配字符:

  • (a-z)作为范围,或以下任何字符:abcdefghijklmnopqrstuvwxyz
  • (A-Z)作为范围,或以下任何字符:ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • ( )一个空间字符
  • (')单引号字符
  • ( -`)一个空格作为一个范围,或以下任何字符:!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[']^_ `

正如您所看到的,最后三个字符( -`)正在创建一个范围,该范围从unicode 0020(空格)到0060(反勾号),包括所有数字、大写字母、一些特殊字符和连字符本身这就是您的字符串(asdf-'`)实际匹配的原因。

不幸的是,包含任何这些字符的许多其他字符串也是如此:12ab34$!-'`#!/a b?&等。

/^[a-zA-Z ' -`]+$/.test("asdf-'`")   // true
/^[a-zA-Z ' -`]+$/.test("!@#-456")   // true
/^[a-zA-Z ' -`]+$/.test("012#$%678") // true
/^[a-zA-Z ' -`]+$/.test("<a:5:c>")   // true

所以,是的,一定要转义(或者按照上面的水平规则移动连字符),以避免用它创建范围!

您需要更改连字符的顺序或在字符类中对其进行转义。

注意:在字符类内部,连字符具有特殊的含义。您可以将它作为类的第一个或最后一个字符。在一些正则表达式实现中,您还可以将其直接放在范围之后。如果将连字符放在其他位置,则需要在其前面加一个反斜杠,以便将其添加到字符类中。

我想验证。。。即字母字符、连字符、撇号和反引号。

if (/^[a-z'`-]+$/i.test(this.value))

如果您想允许使用空格,只需将其添加回字符类中即可。

^[a-zA-Z ' `-]+$

-定义了一个范围。所以,要么对其进行转义,要么将其保留在末尾,以避免形成无效范围。

请参阅演示。

https://regex101.com/r/qH1uG3/6

在您的正则表达式-`` forms a range of characters between空格中and回勾`

https://jsfiddle.net/a4vGA/55/