Я использую фрагменты регулярных выражений для разбора смайликов на изображения и сталкиваюсь с проблемами с точкой с запятой. Например, смайлик как;) превращается в значок WINK, совпадающий с
/;-?\)/g
и работает в большинстве случаев. Но текст вроде ") также соответствует" WINK ", потому что кавычка на самом деле является html-сущностью (" => "WINK
).
Я попытался поставить перед регулярным выражением жадное совпадение без захвата, чтобы отбросить точки с запятой в сущностях:
(?:"|&|<|>|'|')?
Но полученный шаблон по-прежнему совпадает с точкой с запятой в "
, которую следует пропустить, поскольку он возвращает назад, чтобы удовлетворить необязательную последнюю часть. Я также понял, что все еще будут проблемы с другими законными матчами, такими как ЗЛО: >:) => >:)
.
Похоже, что мне действительно нужно, это отрицание предыдущих html-сущностей, пропущенных через точку с запятой:
(?!"|&|<|>|&apos|')
Но он все еще совпадает, и я не уверен, почему.
Было бы идеально по-прежнему получать возвращенные спички, которые можно заменить оптом без дальнейшей проверки, но я открыт для предложений. Что не подходит, так это сначала разбор html-сущностей, потому что иногда они необходимы и / или являются частью легитимного смайлика (как в случае со ЗЛОМ).
РЕДАКТИРОВАТЬ (некоторые продукты Google):
Я обнаружил (и Брайан также отметил ниже), что положительный внешний вид с нулевой шириной, (?<!regex)
, будет работать по желанию (не отрицательный прогноз с нулевой шириной (?!regex)
).
Как и в регулярно-expressions.info, последний «будет успешным только в том случае, если регулярное выражение в предвкушении не будет совпадать», что звучит правильно, но это не так, когда раздел необязателен.
Напротив, первый «совпадает в позиции, если шаблон внутри прогнозной точки может быть сопоставлен с окончанием в этой позиции», что не совсем понятно, но делает трюк. Поскольку при совпадении используется lookbehind, нет возможности вернуться назад, чтобы удовлетворить последнюю часть регулярного выражения.
Таким образом, полное регулярное выражение выглядит так:
/(?<!"|&|<|>|&apos|');-?\)/g
и это соответствует: ;) => WINK
blah;) => blahWINK
";) => "WINK
при сбое: ")
Тем не менее, он по-прежнему соответствует &quot;) => &quotWINK
, поэтому идеальным вариантом будет более тонкая настройка (например, дополнительное сопоставление точек с запятой вместо амперсандов, если это не приведет к разрыву других смайликов с объектами в них). Люди, печатающие html-сущности в чате, вряд ли придут в любом случае.
В любом случае это будет "достаточно хорошо" - , за исключением того, что javascript не поддерживает отрицательный взгляд позади . Но это стоит объяснить для других реализаций регулярных выражений.