Он доходит до детали реализации: типы значений реализуются по-разному для ссылочных типов.
Если вы принудительно применяете типы значений как ссылочные типы (то есть оставьте их, например, обратившись к ним через интерфейс), вы можете получить дисперсию.
Самый простой способ увидеть разницу - просто рассмотреть Array
: массив типов значений объединяется в память смежно (напрямую), где в качестве массива В ссылочных типах всегда имеется ссылка (указатель) в памяти; объекты, на которые указываются, выделены отдельно.
Другая (связанная) проблема (*) заключается в том, что (почти) все типы ссылок имеют одинаковое представление для целей дисперсии, и много кода не нужно знать о разница между типами, поэтому возможна совпадение и противоречие (и легко реализуются - часто просто за счет исключения дополнительной проверки типов).
(*) Это может рассматриваться как одна и та же проблема. .
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
blockquote>В списке рассылки было множество разных элементов с попытками включить его , но он по-прежнему представляется довольно сложной особенностью, потому что 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 .
Чтобы сказать из заключения, я думаю, что внешний вид JavaScript не реализован, поскольку никто не знает, как он должен себя вести, а существующие реализации показывают, что добавление поддержки look-behind довольно сложно.
JavaScript / ECMAScript отличается от других языков тем, что спецификация включает абстрактную реализацию механизма regex, в то время как большинство других языков останавливается только при описании поведения каждой части синтаксиса регулярного выражения, с небольшим описанием того, как разные токены взаимодействуют друг с другом.
. Реализация взгляда вперед довольно проста. Вам нужно только обработать шаблон внутри внешнего вида таким же образом, как и внешний внешний вид, и выполнить совпадение слева направо в соответствии с обычным, за исключением того, что после успешного выполнения поиска 1) текущая позиция восстанавливается до входа в режим ожидания, и 2) точки выбора внутри look-ahead отбрасываются после того, как они сопоставлены.
Нет ограничений на то, что можно включить в look-ahead, поскольку это очень простое дополнение к существующим естественным средствам сравнения слева направо.
С другой стороны, реализация 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. (Это два разновидности, чье поведение позади, которое я изучил.)
В реализации Microsoft .NET все эти регулярные выражения действительны, поскольку .NET реализует look-behind, используя режим справа налево, со стартовым смещением в текущей позиции. Конструкция look-behind сама по себе не генерирует никакой точки выбора.
Однако, если вы используете группы захвата внутри внешнего вида, она начинает запутываться, поскольку атомы в шаблонах интерпретируются из справа налево, , как показано в этом сообщении . Это недостаток этого метода: вам нужно было бы задуматься о праве справа налево при написании внешнего вида.
Напротив, 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? Самый короткий первый, самый длинный первый или обратная строка? Жадный или нет? Возвращение в результаты?
blockquote>
Javascript
обрабатывает regex
несколько неэффективен, и было бы маловероятно, чтобы из-за этого они выполнили утверждения lookbehind?
– l'L'l
8 May 2015 в 12:24