Javascript отрицательный lookbehind ошибка регулярного выражения в webpack [дубликат]

Он доходит до детали реализации: типы значений реализуются по-разному для ссылочных типов.

Если вы принудительно применяете типы значений как ссылочные типы (то есть оставьте их, например, обратившись к ним через интерфейс), вы можете получить дисперсию.

Самый простой способ увидеть разницу - просто рассмотреть Array: массив типов значений объединяется в память смежно (напрямую), где в качестве массива В ссылочных типах всегда имеется ссылка (указатель) в памяти; объекты, на которые указываются, выделены отдельно.

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

(*) Это может рассматриваться как одна и та же проблема. .

17
задан Community 23 May 2017 в 10:31
поделиться

2 ответа

Сегодня

Lookbehind теперь является официальной частью спецификации ES 2018 .

История

Похоже, в то время Брендан Эйх не знал о том, что его существование (потому что Netscape был построен на более старой версии Perl):

Это было в 1998 году, работа Netscape 4, которую я делала в '97, была основана на Perl 4 (!), но мы предложили ECMA TC39 TG1 (группа JS - все было иначе, включая капитализацию), что-то основано на Perl 5. Мы не получили все, и нам пришлось рационализировать некоторые очевидные причуды.

Я не помню, как lookbehind (появившийся в Perl 5.005 в июле 98 года) был специально выделен. Waldemar может вспомнить больше, я передал ему ключи JS внутри netscape.com, чтобы пойти на mozilla.org.

Если вы играете, чтобы написать предложение или мини-спецификацию (в стиле ES5 даже ), дай мне знать.

/ be

В списке рассылки было множество разных элементов с попытками включить его , но он по-прежнему представляется довольно сложной особенностью, потому что EcmaScript Regular Expressions - это backtracking , а backtracking необходим в lookbehind при работе с группами захвата. Это может привести к таким проблемам, как катастрофическое обратное отслеживание при неправильном использовании.

В какой-то момент это было предложено для ES6 / Es 2015, но оно никогда не делало проект, не говоря уже о спецификации , В последнем выпуске в обсуждении кажется, что никто не взял на себя задачу его реализации. Если кто-то чувствует себя призванным для написания реализации, они могут зарегистрироваться для ES Обсудить список и предложить его.

Обновление до 2015 года:

В мае 2015 года , Nozomu Katō предложил реалистичную реализацию ES7 .

Обновление сентябрь 2015:

Regex Look-behind был добавлен как этап 0 Предложение .

Обновление мая 2017 года:

Предложение находится на этапе 3 . Это означает, что теперь по крайней мере два браузера должны реализовать его, чтобы он стал частью следующего стандарта EcmaScript. Как отметил @martixy в комментариях, Chrome реализовал его за экспериментальным флагом JS .

22
ответ дан nils 16 August 2018 в 05:09
поделиться
  • 1
    Как ссылка MSDN имеет какое-либо отношение к заявлению о взгляде здесь? И как можно смотреть за причиной катастрофического возврата? – nhahtdh 8 May 2015 в 08:37
  • 2
    @vks: В зависимости от реализации, внешний вид переменной длины может не вызывать обратную трассировку. Катастрофический откат обычно вызывается другими частями рисунка. – nhahtdh 8 May 2015 в 08:47
  • 3
    @stribizhev: Конечно, вы можете ссылаться на него, но имеет ли он какое-либо отношение к этой проблеме? Я не могу найти ничего, что говорило бы о взгляде. – nhahtdh 8 May 2015 в 08:47
  • 4
    @nils: Образец внутри lookbehind (или любого обратного пути) никогда не возвращается в исходное состояние - это означает, что как только вы выходите из поиска, вы не возвращаетесь обратно внутрь него, а скорее перед поиском. Однако во время проверки проверки, помимо обратного отслеживания, выполненного внутри шаблона, сам lookbehain может быть реализован с возвратом или нет. – nhahtdh 8 May 2015 в 09:03
  • 5
    Хорошие люди из проекта V8 уже внедрили эту функцию. Это, так как несколько дней назад, доступно в стабильном Chrome v49 за флагом Experimental JavaScript. ( v8project.blogspot.bg/2016/02/regexp-lookbehind-assertions.html [/ д0]) – martixy 12 March 2016 в 16:26

Чтобы сказать из заключения, я думаю, что внешний вид JavaScript не реализован, поскольку никто не знает, как он должен себя вести, а существующие реализации показывают, что добавление поддержки look-behind довольно сложно.

JavaScript / ECMAScript отличается от других языков тем, что спецификация включает абстрактную реализацию механизма regex, в то время как большинство других языков останавливается только при описании поведения каждой части синтаксиса регулярного выражения, с небольшим описанием того, как разные токены взаимодействуют друг с другом.

Взгляд? Легко реализовать

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

Нет ограничений на то, что можно включить в look-ahead, поскольку это очень простое дополнение к существующим естественным средствам сравнения слева направо.

Look-behind? Не так просто

С другой стороны, реализация look-behind не так прямолинейна.

Представьте себе, как реализовать следующую конструкцию look-behind:

(?<=fixed-string)
(?<=a|fixed|string)
(?<=t[abc]{1,3})
(?<=(abc){2,6})
(?<=^.*abc.*)
(?<=\G"[^"]+");
(?<=^(.....|.......)+)
\b(\w+)\b(?<!\b\1\b.*\1)

Помимо основного случая (?<=fixed-string), который должна поддерживаться любой реалистичной реализацией, (?<=a|fixed|string) - очень желательный случай для поддержки.

У разных двигателей регулярных выражений различный уровень поддержки для регулярного выражения выше.

Давайте посмотрим, как они реализованы в .NET и Java. (Это два разновидности, чье поведение позади, которое я изучил.)

.NET-реализация

В реализации Microsoft .NET все эти регулярные выражения действительны, поскольку .NET реализует look-behind, используя режим справа налево, со стартовым смещением в текущей позиции. Конструкция look-behind сама по себе не генерирует никакой точки выбора.

Однако, если вы используете группы захвата внутри внешнего вида, она начинает запутываться, поскольку атомы в шаблонах интерпретируются из справа налево, , как показано в этом сообщении . Это недостаток этого метода: вам нужно было бы задуматься о праве справа налево при написании внешнего вида.

Реализация Java

Напротив, Java regex реализация реализует look-back путем повторного использования возможностей совпадения слева направо.

Сначала анализирует шаблон внутри внешнего вида для минимальной и максимальной длины шаблона. Затем, look-behind реализуется, пытаясь сопоставить шаблон внутри слева направо, начиная с (current position - minimum length) до (current position - maximum length).

Не хватает ли чего-нибудь? Да! Поскольку мы сопоставляем слева направо, мы должны убедиться, что совпадение заканчивается прямо в позиции перед входом в look-behind (current position). В Java это реализуется путем добавления узла в конец шаблона внутри look-behind.

Эта реализация очень неэффективна, так как есть maximum - minimum + 1 точки выбора, созданные в самом внешнем виде, прежде чем мы даже поговорим о точках выбора, созданных шаблоном внутри look-behind.

Проверка привязки внешнего вида также неэффективна, поскольку она помещается в конец шаблона и не может обрезать

Резюме

Как вы можете видеть, добавление поддержки look-behind не является easy:

  • Подход справа налево представляется достаточно эффективным. Тем не менее, он требует дополнительной спецификации для сопоставления справа налево в других существующих конструкциях.
  • Подход к повторному использованию объектов соответствия слева направо сложно определить и очень неэффективен. Это также требует введения анализа шаблонов в спецификацию, чтобы производительность не выходила из окна.

(Обратите внимание, что я еще не рассмотрел поведение, когда внешний вид используется внутри

Эти технические препятствия также упоминаются Вальдемар Хорват (который написал спецификацию ES3 regex) в почта указана в ответе nils :

Никто еще не представил четко сформулированное предложение для lookbehinds в таблице. Lookbehinds трудно перевести на язык, используемый спецификацией, и получить довольно нечеткие, когда порядок оценки частей регулярного выражения имеет значение, что и происходит, если речь идет о захвате круглых скобок. Где вы начинаете искать lookbehind? Самый короткий первый, самый длинный первый или обратная строка? Жадный или нет? Возвращение в результаты?

7
ответ дан Community 16 August 2018 в 05:09
поделиться
  • 1
    Спасибо за это понимание / объяснение. Итак, если я правильно понимаю ваш ответ, кажется, что весь путь Javascript обрабатывает regex несколько неэффективен, и было бы маловероятно, чтобы из-за этого они выполнили утверждения lookbehind? – l'L'l 8 May 2015 в 12:24
  • 2
    @ l'L'l: Я отредактировал свой пост, чтобы сделать мой вопрос более ясным. – nhahtdh 8 May 2015 в 16:00
Другие вопросы по тегам:

Похожие вопросы: