JavaScript 字符串说明的正则表达式开始 + str.replace()

JavaScript Regex start of string clarification + str.replace()

有一个关于字符串正则表达式锚标记 ^ 开头的问题。 我试图清理一个字符串以检查它是否是回文,并找到了使用正则表达式的解决方案,但我无法理解我为字符串锚标记开头找到的解释:

据我了解:

^表示后面的任何表达式都必须匹配,从字符串的开头开始。

问题:

为什么下面两个输出之间存在差异:

1)

let x = 'A man, a plan, a canal: Panama';
const re = new RegExp(/[^a-z]/, 'gi');
console.log(x.replace(re, '*'));

输出:A*man**a*plan**a*canal**Panama

VS.

2)

let x = 'A man, a plan, a canal: Panama';
const re = new RegExp(/[a-z]/, 'gi');
console.log(x.replace(re, '*'));

输出:* ***, * ****, * *****: ******

VS.

3)

let x = 'A man, a plan, a canal: Panama';
const re = new RegExp(/^[a-z]/, 'gi');
console.log(x.replace(re, '*'));

输出:* man, a plan, a canal: Panama

如果我对上述每个案例的解释有误,请告诉我:

1) 对此感到困惑。如果它匹配 [a-z] 不区分大小写 + 全局查找的字符 class,字符串锚点的开头 ^ 表示它必须在每个字符串的开头匹配,如果不是 return 句子中的所有单词?由于每个单词都是 [a-z] 不敏感字符的匹配项,这些字符出现在每个全局查找迭代的每个字符串的开头?

(即

问:为什么当我调用 replace 时它只针对非 alpha 内容?在这种情况下,我应该将 ^ 视为反转 [a-z] 吗?

2) 这看起来很简单,找到所有出现的 [a-z] 并将它们替换为开头。 1)的反例??

3) 也对这个一头雾水。我不确定这与 1) 有何不同。

/^[a-z]/gi 对我来说意味着:"starting at the start of the string being looked at, match all alpha characters, case insensitive. Repeat for global find".

相比于:

1) /[^a-z]/gi 对我来说意味着:"match all character class that starts each line with alpha character. case insensitive, repeat search for global find."

意思是他们的意思完全一样@_@。请让我知道我对上述情况的理解有何偏差。

  • 您的第一个表达式 [^a-z] 匹配除字母、小写字母以外的任何内容,因此这就是为什么当您用 * 替换所有特殊字符(如空格、逗号)时和冒号被替换。

  • 您的第二个表达式 [a-z] 匹配任何字母小写字母,因此提到的特殊字符不会被 * 替换。

  • 您的第三个表达式 ^[a-z] 匹配字符串开头的小写字母,因此只有第一个字母被替换为 *

对于前两个表达式,全局标志 g 确保替换所有与指定模式匹配的字符,无论它们在字符串中的位置如何。然而,对于第三个模式,由于 ^ 将模式锚定在字符串的开头,因此仅替换第一个字母。

正如您所提到的,i 标志确保不区分大小写,因此所有三种模式都适用于小写和大写字母,从 azAZ.

字符^因此有两个含义:

  • 它否定字符集中的字符。
  • 它在字符串的开头断言位置。

^ denotes that whatever expression that follows must match, starting from the beginning of the string.

只有当它是正则表达式中的第一件事时才会这样;它在其他地方使用时有其他用途:

/[^a-z]/gi

在上面的正则表达式中,^ 而不是 指示将匹配锚定到字符串的开头;它会反转 [] 的其余内容——所以上面的正则表达式将匹配任何单个字符 除了 a-z。由于您使用的是 g 标志,它将对字符串中的所有字符重复匹配。

/[a-z]/gi

上面没有反转,所以将匹配 a-z 中任何字符的单个实例(并且再次因为 g 标志将重复匹配所有这些实例。)

/^[a-z]/gi

在最后一个示例中,插入符号将匹配锚定到字符串的开头;括号内的部分将匹配任何单个 a-z 字符。 g 标志仍在使用中,因此正则表达式将尝试继续匹配字符串后面的更多字符——但除第一个字符外,其中的 none 将满足锚定到开始的要求, 所以这将最终只匹配第一个字符(如果它在 a-z 内),就像 g 标志没有被使用一样。

(当在正则表达式的开头或 [] 组的开头以外的任何地方使用时,^ 将被视为文字 ^。)

如果您尝试检测回文,您需要删除除字母字符以外的所有字符(并且可能希望将所有字符转换为相同的字母大小写,而不必检测 "P" = = "p":)

const isPalindrome = function(input) {
  let str = input.toLowerCase().replace(/[^a-z]/g,'');
  return str === str.split('').reverse().join('')
}

console.log(isPalindrome("Able was I, ere I saw Elba!"))

console.log(isPalindrome("No, it never propagates if I set a ”gap“ or prevention."))

console.log(isPalindrome("Are we not pure? “No, sir!” Panama’s moody Noriega brags. “It is garbage!” Irony dooms a man –– a prisoner up to new era."))

console.log(isPalindrome("Taco dog is not a palindrome."))