正则表达式 javascript 通过第一个字母匹配第二个字母,但第二个字母必须是大写

Regex javascript match the second letter by the first letter, but the second letter must be an uppercase

此正则表达式匹配第二个字母与第一个字母,但第二个字母不是大写

([a-z])

现在正则表达式匹配像 aa 或 bb 这样的字母,...但我需要我的正则表达式可以匹配所有 aA,bB,...来自这个字符串“abcaAcvbBkl mM

那么如何使正则表达式可以通过第一个值匹配第二个值,但第二个必须是大写

您可以通过以小写模式匹配所有 [a-z] 然后检查每个匹配是否也匹配 [a-z][a-Z]:

来表达这一点

var input = "abcaAcvbBklmMzzQQ";
var matches = input.match(/([a-z])/gi)
                   .filter(x => /^[a-z][A-Z]$/.test(x));
console.log(matches);

我不认为你可以用 只是 一个 JavaScript 正则表达式 (好吧,除非你 )。在某些其他环境中的正则表达式可能能够做到这一点,但JavaScript的不是。

不过 straight-forward 匹配一个 lower-case 字符后跟一个 upper-case 字符,然后过滤掉那些不是 lower-case 的字符,这相当 straight-forward相当于另一个:

const str = "abcaAcvbBklmM";

const results = [];
for (const [, lower, upper] of str.matchAll(/([a-z])([A-Z])/g)) {
    if (lower === upper.toLocaleLowerCase()) {
        results.push(lower + upper);
    }
}

console.log(results);

工作原理:

  • 正则表达式 /([a-z])([A-Z])/g 匹配 lower-case 字母后跟 upper-case 字母(但它们不一定是“相同”字母),在捕获组中捕获每个字母.
  • matchAll 匹配字符串中所有出现的那个,返回结果的迭代器。
  • for-of 循环遍历迭代器的结果。 matchAll 的结果是一个扩充数组,¹ 其中数组中的第一个元素是整体匹配,后跟任何捕获组的元素。该代码在 for-of 中使用解构来挑选数组的第二个和第三个元素(两个捕获组)。
  • 如果第一个字母与转换为小写的第二个字母匹配,则为匹配项,我们将保留它。

我们也可以使用数组方法通过多次遍历而不是单个遍历来做到这一点 for-of:

const str = "abcaAcvbBklmM";

const results = [...str.matchAll(/([a-z])([A-Z])/g)]
    .filter(([, lower, upper]) => lower === upper.toLocaleLowerCase())
    .map(([match]) => match);

console.log(results);


¹ 这段代码没有使用数组的扩充部分,但基本上它除了是一个数组之外还有一个 index 属性 表示匹配发生的位置,一个 groups 属性 包含捕获组信息(我们本可以使用它,但对于这个简单的正则表达式使用数组元素同样容易),以及带有原始内容的 input 属性字符串.

它很难看,但是如果你必须使用一个简单的正则表达式,你可以 brute-force 完整的配对集:

var myText = "aAaaABbCCddEEeEfF";
var letterPairs = myText.match(/aA|bB|cC|dD|eE|fF|gG|hH|iI|jJ|kK|lL|mM|nN|oO|pP|qQ|rR|sS|tT|uU|vV|wW|xX|yY|zZ/g);
console.log(letterPairs);

作为解决方案感觉不是很令人满意,但它会完成工作。

您可以将捕获组与反向引用一起使用,并使用 /i 标志使模式不区分大小写。

然后将匹配的字符串与预期的小写和大写变体进行比较。

const input = "yyabcaAcvbBklmMzzQQ";
const regex = /([a-z])/ig;

const matches = input.match(regex)
  .filter(s =>
    s[0].toLowerCase() + s[1].toUpperCase() === s
  )

console.log(matches);