This regex matches the second letter by the first letter, but the second letter is not an uppercase
([a-z])\1
Now regex matches letters like aa or bb,... but I need that my regex can match all aA,bB,... from this string "abcaA
cvbB
klmM
"
So how to make that regex can match the second value by the first value, but the second must be an uppercase
CodePudding user response:
You could phrase this by matching all [a-z]\1
in lowercase mode and then checking if each match also matches [a-z][a-Z]
:
var input = "abcaAcvbBklmMzzQQ";
var matches = input.match(/([a-z])\1/gi)
.filter(x => /^[a-z][A-Z]$/.test(x));
console.log(matches);
CodePudding user response:
It's ugly as, but if you must use a simple regex, you could just brute-force the full set of pairings:
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);
It doesn't feel very satisfactory as a solution, but it'll get the job done.
CodePudding user response:
I don't think you can do this with just a JavaScript regular expression (well, not unless you list all possible combinations). Regular expressions in some other environments may be able to do it, but not JavaScript's.
It's fairly straight-forward, though, to match a lower-case character followed by an upper-case character and then filter out ones where the one isn't the lower-case equivalent of the other:
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);
How that works:
- The regular expression
/([a-z])([A-Z])/g
matches a lower-case letter followed by an upper-case letter (but they aren't necessarily the "same" letter), capturing each in a capture group. matchAll
matches all occurrences of that in a string, returning an iterator for the results.- The
for-of
loop loops through the results from the iterator. The results frommatchAll
are an augmented array,¹ where the first element in the array is the overall match, followed by elements for any capture groups. The code uses destructuring in thefor-of
to pick out the second and third elements of the array (the two capture groups). - If the first letter matches the second letter converted to lower case, it's a match and we retain it.
We can also do this with multiple passes using array methods rather than a single 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);
¹ This code isn't using the augmented parts of the array, but basically it addition to being an array it has an index
property saying where the match occurred, a groups
property containing capture group information (which we could have used, but it was just as easy to use the array elements for this simple regex), and an input
property with the original string.
CodePudding user response:
You could use the capture group with the backreference and make the pattern case insensitive with the /i
flag.
Then compare the matched string with the expected lower and uppercase variants.
const input = "yyabcaAcvbBklmMzzQQ";
const regex = /([a-z])\1/ig;
const matches = input.match(regex)
.filter(s =>
s[0].toLowerCase() s[1].toUpperCase() === s
)
console.log(matches);