JavaScript Regex字符串开头+ str.replace()

时间:2018-08-04 16:35:13

标签: javascript regex palindrome

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

据我了解:

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

问题:

为什么下面的两个输出之间有区别:

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]不区分大小写+全局查找匹配,且字符串锚点^的开头表示它必须在每个字符串的开头都匹配,则它不应该返回句子中的所有单词?因为每个单词都是[a-z]不敏感字符的匹配项,而这些匹配项在每次全局查找迭代的每个字符串的开头出现?

(即

  • 在开始处找到“ A”
  • 然后在下一次迭代中,它将开始搜索剩余的字符串“ man”
  • 找到空间...然后继续搜索“人”?
  • 依此类推...

问:为什么当我打电话给replace时,它只针对非alpha内容?在这种情况下,我应该将^视为倒退[a-z]吗?

2)这似乎很简单,找到所有[a-z]出现的位置,并将其替换为开头。 1)的反例??

3)也对此感到困惑。我不确定这与1)有何不同。

/^[a-z]/gi对我来说意味着:“从要查看的字符串的开头开始,匹配所有字母字符,不区分大小写。重复进行全局查找”。

相比:

1)/[^a-z]/gi对我的意思是:“匹配所有以字母开头的所有字符类。不区分大小写,重复搜索全局查找。”

表示它们的意思完全相同。请让我知道以上情况对我的理解如何。

2 个答案:

答案 0 :(得分:1)

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

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

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

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

正如您所提到的,i标志可确保不区分大小写,因此所有三种模式都可对小写和大写字母进行操作,从az和{{1} }到A

因此,字符Z具有两个含义:

  • 它会否定字符集中的字符。
  • 它在字符串的开头声明位置。

答案 1 :(得分:1)

  

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

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

/[^a-z]/gi

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

/[a-z]/gi

以上内容并未颠倒,因此将匹配a-z中任何字符的单个实例(同样由于g标志将重复以匹配所有这些实例。)

/^[a-z]/gi

在最后一个示例中,插入符号将匹配项锚定到字符串的开头;方括号部分将匹配任何单个a-z字符。 g标志仍在使用中,因此正则表达式将尝试在字符串的后面继续匹配更多字符-但除第一个字符外,没有其他字符将满足锚定开始的要求,因此这将最终仅与第一个字符匹配(如果它在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."))