Javascript regex - искать альтернативу?
Вот регулярное выражение, которое отлично работает в большинстве реализаций регулярных выражений:
(?<!filename)\.js$
Это соответствует .js для строки, которая заканчивается на .js, за исключением filename.js
Javascript не имеет регулярного выражения. Может ли кто-нибудь собрать альтернативное регулярное выражение, которое достигнет того же результата и работает в javascript?
Вот некоторые мысли, но нужны вспомогательные функции. Я надеялся добиться этого только с помощью регулярного выражения:
http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript
Ответы
Ответ 1
^(?!filename).+\.js
работает для меня
проверено:
- соответствие test.js
- соответствие blabla.js
- filename.js нет соответствия
Правильное объяснение этого регулярного выражения можно найти в Регулярное выражение для соответствия строке, не содержащей слова?
Посмотрите вперед, поскольку версия 1.5 javascript и поддерживается всеми основными браузерами
Обновлено для соответствия filename2.js и 2filename.js, но не filename.js
(^(?!filename\.js$).).+\.js
Ответ 2
EDIT: Начиная с ECMAScript 2018, утверждения lookbehind (даже неограниченные) поддерживаются изначально.
В предыдущих версиях вы можете сделать это:
^(?:(?!filename\.js$).)*\.js$
Это явно указывает на то, что выражение lookbehind делает неявно: проверьте каждый символ строки, если выражение lookbehind плюс регулярное выражение после него не совпадет, и только затем разрешите совпадение этого символа.
^ # Start of string
(?: # Try to match the following:
(?! # First assert that we can't match the following:
filename\.js # filename.js
$ # and end-of-string
) # End of negative lookahead
. # Match any character
)* # Repeat as needed
\.js # Match .js
$ # End of string
Другое редактирование:
Мне больно говорить (тем более, что этот ответ был так популярен), что есть намного более простой способ достичь этой цели. Нет необходимости проверять внешний вид каждого персонажа:
^(?!.*filename\.js$).*\.js$
работает так же хорошо:
^ # Start of string
(?! # Assert that we can't match the following:
.* # any string,
filename\.js # followed by filename.js
$ # and end-of-string
) # End of negative lookahead
.* # Match any string
\.js # Match .js
$ # End of string
Ответ 3
Предположим, вы хотите найти все int
, которым не предшествует unsigned
:
С поддержкой отрицательного внешнего вида:
(?<!unsigned )int
Без поддержки отрицательного внешнего вида:
((?!unsigned ).{9}|^.{0,8})int
В принципе идея состоит в том, чтобы захватить n предшествующих символов и исключить совпадение с отрицательным внешним видом, но также соответствовать случаям, когда нет предшествующих n символов. (где n - длина обратного хода).
Итак, заданное регулярное выражение:
(?<!filename)\.js$
переводится на:
((?!filename).{8}|^.{0,7})\.js$
Вам может потребоваться сыграть с группами захвата, чтобы найти точное место интересующей вас строки, или вы не хотите заменять определенную часть чем-то другим.
Ответ 4
Если вы можете смотреть вперед, но назад, вы можете сначала изменить строку, а затем сделать вид. Конечно, потребуется еще немного работы.
Ответ 5
Это эквивалентное решение ответа Тима Питцкера (см. также комментарии того же ответа):
^(?!.*filename\.js$).*\.js$
Это означает, что соответствует *.js
кроме *filename.js
.
Чтобы перейти к этому решению, вы можете проверить, какие шаблоны отрицательный lookbehind исключает, а затем исключить именно эти шаблоны с отрицательным видом.
Ответ 6
Ниже представлена положительная альтернатива JavaScript, показывающая, как записать фамилию людей с именем "Майкл" в качестве их имени.
1) С учетом этого текста:
const exampleText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?";
получить массив фамилий людей по имени Майкл.
Результат должен быть: ["Jordan","Johnson","Green","Wood"]
2) Решение:
function getMichaelLastName2(text) {
return text
.match(/(?:Michael )([A-Z][a-z]+)/g)
.map(person => person.slice(person.indexOf(' ')+1));
}
// or even
.map(person => person.slice(8)); // since we know the length of "Michael "
3) Проверьте решение
console.log(JSON.stringify( getMichaelLastName(exampleText) ));
// ["Jordan","Johnson","Green","Wood"]
Демо здесь: http://codepen.io/PiotrBerebecki/pen/GjwRoo
Вы также можете попробовать, выполнив сниппет ниже.
const inputText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?";
function getMichaelLastName(text) {
return text
.match(/(?:Michael )([A-Z][a-z]+)/g)
.map(person => person.slice(8));
}
console.log(JSON.stringify( getMichaelLastName(inputText) ));