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)    ));