Как найти индексы всех несоответствующих символов с помощью регулярного выражения JS? - PullRequest
0 голосов
/ 04 марта 2019

У меня есть строка, и я хочу получить массив с индексами (позициями) символов в этой строке, которые не соответствуют определенным критериям регулярного выражения.

Проблема в том, что если янапишите это так:

let match;
let reg = /[A-Za-z]|[0-9]/g;
let str = "1111-253-asdasdas";
let indexes = [];

do {
    match = reg.exec(str);
    if (match) indexes.push(match.index);
} while (match);

Это работает.Возвращает индексы всех символов, которые являются числовыми или алфавитными.Но проблема в том, что если я попытаюсь сделать обратное, с отрицательным взглядом в Regex, как это:

let match;
let reg = /(?!([A-Za-z]|[0-9]))/g;
let str = "1111-253-asdasdas";
let indexes = [];

do {
    match = reg.exec(str);
    if (match) indexes.push(match.index);
} while (match);

Это заканчивается бесконечным циклом.

Что бы яКак достичь, тот же результат, что и в первом случае, но с отрицательным регулярным выражением, поэтому в этом случае результат будет следующим:

indexes = [4, 8]; // which are the indexes in which a non-alphanumerical character appears

Является ли цикл неправильным, или это выражение регулярного выражения - тот, ктовсе портит?Может быть, exec не работает с выражениями Regex с отрицательными взглядами?

Я бы понял, что выражение Regex работает не так, как я хотел (потому что оно может быть неправильно отформатировано), но я не понимаю бесконечный циклЭто заставляет меня думать, что exec возможно, это не лучший способ достичь того, что я ищу.

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Причина

Бесконечный цикл легко объяснить: регулярное выражение имеет модификатор g и, таким образом, пытается сопоставить множественные вхождения шаблона, начиная каждую попытку сопоставления после окончанияпредыдущее успешное совпадение, то есть после значения lastIndex:

См. exec документация :

Если вашрегулярное выражение использует флаг "g", вы можете использовать метод exec() несколько раз, чтобы найти последовательные совпадения в одной и той же строке.При этом поиск начинается с подстроки str, указанной в свойстве lastIndex регулярного выражения

Однако, поскольку ваш шаблон соответствует пустой строке, ивы не проверяете условие, если индекс равен lastIndex, регулярное выражение не может продвигаться в строке.

Решение

Используйте регулярное выражение, чтобы сопоставить любое небуквенно-цифровые символы, /[\W_]/g.Поскольку он не соответствует пустым строкам, свойство lastIndex объекта RegExp будет изменяться при каждом совпадении, и бесконечный цикл не будет выполняться.

JS demo:

let match, indexes = [];
let reg = /[\W_]/g;
let str = "1111-253-asdasdas";

while (match = reg.exec(str)) {
    indexes.push(match.index);
}
console.log(indexes);

Также см. , как вручную перемещать значение свойства lastIndex .

0 голосов
/ 04 марта 2019

При таком подходе все совпадающие символы заменяются звездочкой *.Затем мы повторяем эту замененную строку и извлекаем все индексы, которые не соответствуют классу символов регулярного выражения.

var str = "1111-253-asdasdas";
var pattern = /[^A-Za-z0-9]/g;
str = str.replace(pattern, "*");

var indices = [];
for(var i=0; i < str.length;i++) {
    if (str[i] === "*") indices.push(i);
}
console.log(indices.toString());

В этом случае не совпадают только символы в позициях 4 и 8, поскольку они являются подчеркиванием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...