JavaScript正则表达式字符串澄清开头+ str.replace()

问题描述 投票:0回答:2

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

To my understanding:

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

Question:

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

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]and都用开头替换它们。逆情况1)??

3)也对这个感到困惑。我不确定这与1)有什么不同。

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

相比:

1)/[^a-z]/gi对我意味着:“匹配所有使用alpha字符开始每一行的字符类。不区分大小写,重复搜索全局查找。”

意思是他们的意思完全相同@ _ @。请告诉我对上述案例的理解。

javascript regex palindrome
2个回答
1
投票
  • 你的第一个表达式[^a-z]匹配除了字母小写字母以外的任何内容,因此当你用*替换时,所有特殊字符(如空格,逗号和冒号)都会被替换。
  • 你的第二个表达式[a-z]匹配任何字母小写字母,因此提到的特殊字符不会被*取代。
  • 你的第三个表达式^[a-z]匹配字符串开头的字母小写字母,因此只有第一个字母被*替换。

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

正如你所提到的,i标志确保不区分大小写,因此所有三种模式都可以在大小写字母上运行,从azAZ

因此,^这个角色有两个含义:

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

1
投票

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

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

/[^a-z]/gi

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

/[a-z]/gi

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

/^[a-z]/gi

在最后一个例子中,插入符号将匹配锚定到字符串的开头;括号内的部分将匹配任何单个a-z字符。 g标志仍在使用中,因此正则表达式将尝试在字符串中稍后继续匹配更多字符 - 但除了第一个之外,其中没有一个将满足锚定到开始的要求,因此这将最终仅匹配第一个字符(如果它在az内),就像没有使用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."))
© www.soinside.com 2019 - 2024. All rights reserved.