2
Hello, I have a string (var test
), and would like to perform some operations on it. The desired result is a number, preceded by or of the letter p, s, or ps (NAY sp) (ex: ps1), and a number followed by any letter of a-z, in any quantity, but without repeating the same letters (ex: p1abd, would correspond, BUT p1abbd not because there was repetition of one of the letters, the letter b. (That part of avoiding repetition could not perform). It seemed ideal to use test[i].match(/\b(p|s|ps)\d[a-z]*\b/)
, however, as you can see in the 1st Example, the array comes with 2 values, the second being the letter(s) before the number, undesirable, I just want a value, the first. I think this has something to do with parentheses, but I couldn’t get another combination that worked. In the 2nd example, it appears exactly as I want, but the regex is wrong because it relates any combination of the letters p and s, but does not list the letters ps. Already in the 3rd Example I want to eliminate everything except the letters after the number, but I had problems probably because of the Array c/ two values. And in the 4th Example I want to delete everything except the number between the letters. In the case of the 3rd and 4th Examples, I know that there are simpler ways to accomplish this, such as: test[i].match(/\d/g).toString()
, to display only the number. But I would like to know, for learning purposes, how to isolate the number of the pattern to be deleted, as I did in the 3rd Example. I tried something like: ...replace(/[p|s|ps][^\d][a-z]*/, ''))
, but it didn’t work.
var test = 'xyz p1abc xyz; xyz s3de xyz; xyz ps2fgh xyz'; // p1abc, s3de, ps2fgh
test = test.split(';');
for (var i = 0; i < test.length; i++) {
test[i] = test[i].replace(/^\s+|\s+$/g, '');
// Exibir as letras 'p', 's', ou 'ps' ANTES do nº, e qualquer letra APÓS o nº em qualquer quantidade.
console.log(test[i].match(/\b(p|s|ps)\d[a-z]*\b/)); // 1º Exemplo
// Resultado:
Array [ "p1abc", "p" ] // repete a letra p
Array [ "s3de", "s" ] // repete a letra s
Array [ "ps2fgh", "ps" ] // repete as letras ps
console.log(test[i].match(/\b[p|s|ps]\d[a-z]*\b/)); // 2º Exemplo
// Só não funciona porque não inclui o 'ps'. Resultado:
Array [ "p1abc" ]
Array [ "s3de" ]
null
// Exibir só as letras APÓS o número. ([a-z]*) // 3º Exemplo
console.log(test[i].match(/\b[p|s|ps]\d[a-z]*\b/).toString().replace(/[p|s|ps]\d[^a-z]*/, ''));
// Novamente, só não funciona porque não inclui o 'ps'. Resultado:
TypeError: test[i].match(...) is null
"abc"
"de"
// Exibir só o número. (\d) // 4º Exemplo
console.log(test[i].match(/\b[p|s|ps]\d[a-z]*\b/).toString().replace(/[p|s|ps]\d[a-z]*/, ''));
// Para este não achei solução.
}
Is it really necessary to use regex for that? If you identified the pattern, took your parts with capture groups, then you can replace/match them the way you want by simply concatenating those parts. Anyway, I updated the answer with a note about substitutions. In short, you keep the prefix with
replace(/\b(p|s|ps)(\d)([a-z]*)\b/, '$1')
and the digit withreplace(/\b(p|s|ps)(\d)([a-z]*)\b/, '$2')
, for example (there are other ways).– mgibsonbr
@mgibsonbr, I examined your explanation well and everything was clear p/me. I stored the result in
var s = test[i].match(\b(p|s|ps)(\d)((?:([a-z])(?!.*\4))*)\b);
, and now access each capture group by its contents. Ex:s[0]
and/ors[2]
..., economic good. Thanks for the help! However, when the value of the variable test repeats even a single letter of the alphabetic suffix (3rd capture group), no match. Ex:var test = 'xyz p1abc cde
does not match because of the letter c in Cde, even though we are outside the limits of the search.– eden
In fact, Lookahead checks to the end... Try replacing the
.
on the other hand[a-z]
, so he should stop looking for repetitions where he shouldn’t:\b(p|s|ps)(\d)((?:([a-z])(?![a-z]*\4))*)\b
(example)– mgibsonbr