使用RegExp理解一些JavaScript

使用RegExp理解一些JavaScript,javascript,regex,Javascript,Regex,我有以下js代码 var regex = new RegExp('([\'"]?)((?:\\\\\\1|.)+?)\\1(,|$)', 'g'), key = regex.exec( m ), val = regex.exec( m ); 我想了解它。 特别是: 为什么在RegExp的定义中有这么多反斜杠?我可以清楚地看到,\\1是对第一个保存元素的引用。为什么在新的RegExp中使用“and not”我们需要使用\\1而不是简单的\1 为什么key和val的两个定义之间有一个逗号?我可能

我有以下js代码

var regex = new RegExp('([\'"]?)((?:\\\\\\1|.)+?)\\1(,|$)', 'g'),
key = regex.exec( m ),
val = regex.exec( m );
我想了解它。 特别是:

  • 为什么在RegExp的定义中有这么多反斜杠?我可以清楚地看到,
    \\1
    是对第一个保存元素的引用。为什么在新的RegExp中使用“and not”我们需要使用
    \\1
    而不是简单的
    \1

  • 为什么
    key
    val
    的两个定义之间有一个逗号?我可能猜这取决于使用
    “g”
    查找的“实例”,但我并不十分清楚

我试着用

m = 'batman, robin' 
结果是一团糟,我无法很好地解释


代码取自JQuery Cookbook,2.12

在编写动态正则表达式对象和静态正则表达式对象时存在差异。当您使用字符串初始化正则表达式对象时,需要将其转换为正则表达式对象。但是,“\”不仅在正则表达式对象中具有特殊值,而且在javascript字符串中也具有特殊值,因此双重逃跑

编辑:关于第二个问题。您可以使用逗号进行多个声明,如下所示:

var one = 'one',
    two = 'two',
    three = 'three';
第二次编辑:下面是字符串编译成正则表达式对象后的情况

/(['"]?)((?:\\\1|.)+?)\1(,|$)/g

在编写动态正则表达式对象和静态正则表达式对象时存在差异。当您使用字符串初始化正则表达式对象时,需要将其转换为正则表达式对象。然而,“\”不仅在正则表达式对象中包含特殊值,而且在javascript字符串中也包含特殊值,因此出现了双转义

编辑:关于第二个问题。您可以使用逗号进行多个声明,如下所示:

var one = 'one',
    two = 'two',
    three = 'three';
第二次编辑:下面是字符串编译成正则表达式对象后的情况

/(['"]?)((?:\\\1|.)+?)\1(,|$)/g
为什么在RegExp的定义中有这么多反斜杠

“\\”
是一个值为
\
的字符串。一个反斜杠用作转义,第二个用作值。然后,在正则表达式中,您还需要再次转义反斜杠字符,因为反斜杠字符用于表示正则表达式中的特殊内容

比如说

"\\1"
是一个字符串,其值为
\1
,在正则表达式中与第一个捕获的组匹配

"\\\\"
是一个字符串,其值为
\\
,在正则表达式中与单个
\
字符匹配

"\\\\\\1"
是一个字符串,其值为
\\\1
,在正则表达式中,它与单个
\
匹配,后跟第一个捕获的组

"\\\\"
这种需要逃逸反斜杠,然后再次逃逸的行为称为“双重逃逸”“。需要双重转义的原因是为了在正则表达式中具有正确的值。第一个转义是确保字符串具有正确的值,第二个转义是使正则表达式匹配正确的模式

为什么key和val的两个定义之间有逗号

您发布的代码是一个变量声明。格式化时更容易看到:

var regex = ...,
    key = ...,
    val = ...;
列表中的每个变量名都是通过
var
关键字声明的。这与单独声明关键字相同:

var regex,
    key,
    val;

regex = ...
key = ...
val = ...
这与使用不同的var关键字声明每个var相同:

var regex = ...
var key = ...
var val = ...
为什么在RegExp的定义中有这么多反斜杠

“\\”
是一个值为
\
的字符串。一个反斜杠用作转义,第二个用作值。然后,在正则表达式中还需要再次转义反斜杠字符,因为反斜杠字符用于表示正则表达式中的特殊内容

比如说

"\\1"
是一个字符串,其值为
\1
,在正则表达式中与第一个捕获的组匹配

"\\\\"
是一个字符串,其值为
\\
,在正则表达式中与单个
\
字符匹配

"\\\\\\1"
是一个字符串,其值为
\\\1
,在正则表达式中,它与单个
\
匹配,后跟第一个捕获的组

"\\\\"
这种需要避开反斜杠,然后再次避开它们的行为称为“双重逃避”。需要双重转义的原因是为了在正则表达式中具有正确的值。第一个转义是确保字符串具有正确的值,第二个转义是使正则表达式匹配正确的模式

为什么key和val的两个定义之间有逗号

您发布的代码是一个变量声明。格式化时更容易看到:

var regex = ...,
    key = ...,
    val = ...;
列表中的每个变量名都是通过
var
关键字声明的。这与单独声明关键字相同:

var regex,
    key,
    val;

regex = ...
key = ...
val = ...
这与使用不同的var关键字声明每个var相同:

var regex = ...
var key = ...
var val = ...

正则表达式最好表示为正则表达式文字:

var regex = /(['"]?)((?:\\\1|.)+?)\1(,|$)/g;
反斜杠用于转义特殊字符。例如,如果您的正则表达式需要匹配文字句点,那么写入
将不起作用,因为
匹配任何字符:您需要使用反斜杠“转义”句点:
\。

必须对本身不属于转义序列的反斜杠进行转义,因此如果只想匹配文本中的反斜杠,则必须使用反斜杠进行转义:
\\

当将正则表达式传递到
RegExp
构造函数时,它之所以如此复杂,是因为您将上述正则表达式表示为字符串,这会添加另一个转义“层”。因此,每一个反斜杠都必须由另一个反斜杠转义,并且由于字符串包含在单引号中,因此单引号必须由另一个反斜杠转义:

var regex = new RegExp('([\'"]?)((?:\\\\\\1|.)+?)\\1(,|$)', 'g'),

正则表达式最好表示为正则表达式文字:

var regex = /(['"]?)((?:\\\1|.)+?)\1(,|$)/g;
反斜杠用于转义特殊字符。例如,如果您的正则表达式需要匹配一个文字句点,那么编写