регулярное выражение JavaScript - искать альтернативу? - PullRequest
132 голосов
/ 11 сентября 2011

Вот регулярное выражение, которое отлично работает в большинстве реализаций регулярного выражения:

(?<!filename)\.js$

Это соответствует .js для строки, которая заканчивается на .js за исключением filename.js

Javascript не имеет регулярных выражений. Кто-нибудь может собрать альтернативное регулярное выражение, которое достигает того же результата и работает в JavaScript?

Вот некоторые мысли, но нужны вспомогательные функции. Я надеялся достичь этого просто с помощью регулярного выражения: http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript

Ответы [ 6 ]

143 голосов
/ 11 сентября 2011

РЕДАКТИРОВАТЬ: Начиная с ECMAScript 2018 года, утверждения за кадром (даже неограниченные) поддерживаются изначально .

В предыдущих версиях вы можете сделать это:

^(?:(?!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
60 голосов
/ 11 сентября 2011

^(?!filename).+\.js работает для меня

проверено на:

  • test.js match
  • blabla.js match
  • filename.jsнет совпадений

Правильное объяснение этому регулярному выражению можно найти по адресу Регулярное выражение для сопоставления строки, не содержащей слова?

Просмотр вперед доступен с версия 1.5 javascript и поддерживается всеми основными браузерами

Обновлено для соответствия имени filename2.js и 2filename.js, но не filename.js

(^(?!filename\.js$).).+\.js

23 голосов
/ 30 ноября 2014

Предположим, вы хотите найти все int, которым не предшествует unsigned:

С поддержкой негативного просмотра:

(?<!unsigned )int

Без поддержки негативного просмотра:

((?!unsigned ).{9}|^.{0,8})int

В основном идея состоит в том, чтобы захватить n предшествующих символов и исключить совпадение с отрицательным прогнозом, но также сопоставить случаи, когда нет предшествующих n символов. (где n - длина оглядки назад).

Итак, регулярное выражение в вопросе:

(?<!filename)\.js$

будет переводиться на:

((?!filename).{8}|^.{0,7})\.js$

Возможно, вам придется поиграть с группами захвата, чтобы найти точное место строки, которая вас интересует, или вы не хотите заменять конкретную часть чем-то другим.

5 голосов
/ 26 ноября 2015

Если вы можете смотреть вперед, но назад, вы можете сначала перевернуть строку, а затем сделать заглядывание вперед. Конечно, нужно проделать еще кое-что.

0 голосов
/ 16 мая 2017

Это эквивалентно решению Ответ Тима Пицкера (см. Также комментарии того же ответа):

^(?!.*filename\.js$).*\.js$

Это означает, соответствует *.js, за исключением *filename.js.

Чтобы добраться до этого решения, вы можете проверить, какие образцы исключает отрицательный взгляд, а затем исключить именно эти образцы с отрицательным взглядом.

0 голосов
/ 19 октября 2016

Ниже приведен положительный обзор альтернативы 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?";

getмассив фамилий людей по имени Майкл.Результат должен быть: ["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)    ));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...