正则表达式中$ 0和$ 1

时间:2013-09-08 21:57:02

标签: javascript regex

我正在尝试使用正则表达式替换,需要一些帮助来理解$ 1在此代码中的含义。此代码用于交换案例。

return str.replace(/([a-z])|([A-Z])/g,
    function($0, $1)
    { return ($1) ? $0.toUpperCase() : $0.toLowerCase(); })

我理解在替换方法的第一个参数中我检查我们是否有小写或大写字母,但我不明白如何以及如何使用第二个参数。

我理解if($ 1)为真的语法,我们执行$ 0.toUpperCase(),否则我们执行$ 0.toLowerCase()。但是如何判断($ 1)是真的呢? ($ 1)有什么条件?我想我理解$ 0是整个匹配的字符串。但我很困惑($ 1)。谢谢!

4 个答案:

答案 0 :(得分:2)

  

($ 1)有什么条件?

无 - 正则表达式语法不指定如何评估匹配组的真实性,因此这取决于包含语言的行为。

我猜测,在这种情况下,它将空字符串评估为false,将非空字符串评估为true - 但是您还没有告诉我们这是什么语言,我无法确定。

答案 1 :(得分:1)

$0确实是整个匹配的字符串。 $1是第一个子模式(即小写字母)。如果第一个子模式匹配,我们将其大写,否则我们将其小写。应该注意的是,该函数有另一个参数,但在这种情况下不使用它。

答案 2 :(得分:1)

Note the parameters passed to the evaluator。按照给出的模式,我把它重写为:

str.replace(/([a-z])|([A-Z])/g,
  function(match, p1, p2) {
    return p1 ? p1.toUpperCase() : p2.toLowerCase();
  })

如果([a-z])匹配,则绑定的p1$1)变量将评估为truthy-string(任何非空的字符串;特别是,一个被接受的字符串正则表达式);否则p1将是空字符串""(这是一个假值)。这就是对p1$1)的检查正确的原因 - 请注意绑定的捕获组总是具有字符串类型。

请注意,没有必要检查match$0)因为它永远不会是正则表达式(它将是第一个或第二个交替子表达式)

答案 3 :(得分:0)

在这个例子中,<0> $ 0和$ 1只是变量(使用匈牙利表示法命名)。您可以使用a和b轻松替换它们,代码的工作方式相同。使用许多参数调用该函数。第一个参数是匹配的子字符串。第二个参数是第一个捕获(与第一个括号中的正则表达式匹配的任何内容,在本例中是单个小写字母a-z)。第三个(缺失)参数将是第二个捕获(匹配大写字母A-Z),但请注意这将被忽略。

因为正则表达式使用全局&#34; g&#34;标志,该函数被(可能)多次调用。正则表达式匹配任何小写或大写字母。第一个函数参数将匹配str中的每个字符,第二个参数仅在第一个捕获组匹配时设置 - 意味着仅当字符为小写时才设置第二个函数参数。如果设置了第二个参数(即这是一个小写字符),则在匹配时调用toUpperCase函数。如果未设置第二个参数(即这是一个大写字符),则在匹配时调用toLowerCase函数。在后一种情况下,未使用的第三个参数包含第二个捕获组内容。

整个解决方案具有逐个字符交换案例的效果。

但是..在这段代码中使用$ 0和$ 1表明创建者正在玩弄其他东西:引用和反向引用。 $ 0(或某些语言中的\ 0)是对匹配的引用(即它恰好是函数的第一个参数),$ 1(或\ 1)是对第一个捕获组的引用,等等。此代码的作者将这些变量命名为支持第一个参数等价于$ 0而第二个参数等于$ 1等概念。在我看来,这是开明的,完全令人困惑的。使用这些变量名称表明正在发生一些神奇的事情。使用匈牙利表示法也意味着别的东西。这里没有任何魔法,因此变量应该更简单命名 - 匹配和is_lowercase就可以了。

此外,由于缺少第三个函数参数,因此不需要捕获大写字符类。