Can negation in regex in Notepad++ match emoji or other unicode char at U+10000 and above outside the Basic Multilingual Plane (BMP)?

It seems the regex engine used by Notepad++ can't do what I thought it would. Maybe a more general problem, not only with negation syntax.

Example with unicode number U+1F3B5, Unicode Name "Musical Note":

Successful regex WITHOUT negation that is already matching what I want:

videoPrimaryInfoRenderer":{"title":{"runs":\[{"text":"\K.+?(? = ")

Example text that includes something I want to match:

}},"contents":{"twoColumnWatchNextResults":{"results":{"results":{"contents":[{"videoPrimaryInfoRenderer":{"title":{"runs":[{"text":"【みんなのリズム会場】ノリノリリズムパーティーはこちらです!🎵【天国】"}]},"viewCount":{"videoViewCountRenderer":

The part that I want to match (the regex above gets this):

【みんなのリズム会場】ノリノリリズムパーティーはこちらです!🎵【天国】

includes

🎵

emoji. So the "dot" DOES match characters above U+10000 in the last part of my regex:

.+?

and then the lookahead

(? = ")

ends the match before the first ".


AFTER:

videoPrimaryInfoRenderer":{"title":{"runs":\[{"text":"\K

with the \K modifier to "forget" about that part and select whatever I put at the end of that regex...

Example regex with negation I tried:

Example 1:

[^"]+

since there is no " in the part I want to match, matched:

【みんなのリズム会場】ノリノリリズムパーティーはこちらです!

Example 2:

((?!").)+

matched the same as example 1. Not surprising, since it's the same idea of excluding " but with negative lookahead.

Both types of "match OTHER THAN specified character" stop before the emoji.

Notepad++ v8.6.5 (32-bit)

I would appreciate an explanation.

Я думаю, что есть ошибка: \X должен соответствовать всем графемам (вместо .), но это не так. По сути, здесь существует огромная проблема с совпадением символов Юникода.

Wiktor Stribiżew 23.04.2024 09:11

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

anon 24.04.2024 00:12

На основании чего вы определяете, публиковать ли ответ в комментарии или в основном ответе?

anon 24.04.2024 00:54

Очень короткий ответ (я эксперт по Unicode): регулярные выражения Notepad++ не могут правильно обрабатывать символы, отличные от BMP.

Lover of Structure 20.05.2024 09:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
4
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

TLDR:

Вы можете использовать

videoPrimaryInfoRenderer":{"title":{"runs":\[{"text":"\K(?:(?!").[\x{DC00}-\x{DFFF}]?)+

Вы можете обратиться к Regexp не соответствует символам UTF-8 Сообщение сообщества Notepad++:

К сожалению, в классах символов, о которых вы упомянули, это означает, что символы за пределами BMP (с U+10000 и выше), хотя их можно найти с помощью ^.+, не могут быть найдены с помощью чего-то, что кажется эквивалентным, например ^[\s\S]+

Проблемы возникают при поиске символов Юникода, находящихся в базовой многоязычной плоскости (BMP), кодовая точка которых находится между \x{10000} и \x{10FFFF} (то есть над \x{FFFF}).

Например, когда код смайла 🤣 закончился \x{FFFF}:

  • Его невозможно представить в реальном синтаксисе регулярных выражений \x{1F923} из-за ошибки нынешнего механизма регулярных выражений Boost, который обрабатывает не все символы в истинной 32-битной кодировке, а только в кодировке UTF-16:-(( Итак, ищем \x{1F4A6} приводит к сообщению об ошибке Find: Invalid regular expression
  • Более того, простой символ точки (?-s). в регулярном выражении не может соответствовать символу, а также кодовой точке Unicode > \x{FFFF}!
  • Конечно, если вы вставите свой персонаж непосредственно в зону «Найти что:», он обнаружит все вхождения символа ROLLING ON THE FLOOR LAUGHING!

К счастью, кодирование символов нашего механизма регулярных выражений Boost в UTF-16 позволяет кодировать все символы, начиная с кодовой точки \x{FFFF}, благодаря механизму суррогатов. См. общие сведения ниже:

https://en.wikipedia.org/wiki/UTF-16

Короче говоря, суррогатную пару символов с кодовой точкой Unicode в диапазоне от \x{10000} до \x{10FFFF} можно описать регулярным выражением:

\x{hhhh}\x{iiii} где D800 < hhhh < DBFF и DC00 < iiii < DFFF

Таким образом, если регулярное выражение включает в себя пару суррогатов (два 16-битных блока) символа, который находится над BMP, наш механизм регулярных выражений сможет сопоставить его. Например, поскольку суррогатной парой символа ROLLING ON THE FLOOR LAUGHING является D83E DD23, регулярное выражение \x{D83E}\x{DD23} находит все вхождения вашего смайлика!

и недавно я предложил макрос Notepad++, который заменяет любой выбор синтаксиса \xhhhhh их суррогатными парными эквивалентами \x{Dhhh}\x{Diii} ! Смотрите ниже :
https://community.notepad-plus-plus.org/post/57528

Резюме:

Таким образом, из-за использования UTF-16 вместо UTF-32 в настоящей реализации библиотеки Boost Regex в N++:

  • Используйте простое регулярное выражение (?-s). для соответствия любому стандартному символу от \x{0000} до \x{FFFF} (не включая символы EOL и символы подачи формы \x0c).

  • ВАЖНО: Из механизма суррогатов, описанного выше, можно подумать, что регулярное выражение [\x{D800}-\x{DBFF][\x{DC00}-\x{DFFF}] должно найти все символы с кодовой точкой Юникода над \x{FFFF}. К сожалению, этот синтаксис не работает!? Итак, нам нужно использовать эти производные регулярные выражения:

  • (?-s).[\x{DC00}-\x{DFFF}] для соответствия любому стандартному символу от \x{10000} до \x{10FFFF}

  • (?-s).[\x{DC00}-\x{DFFF}]?, чтобы соответствовать всем стандартным символам, от \x{0000} до \x{10FFFF}

И :

  • Чтобы сопоставить определенный символ BMP, от \x{0000} до \x{FFFF}, используйте синтаксис регулярного выражения \x{hhhh} с четырьмя шестнадцатеричными числами.

  • Чтобы сопоставить определенный символ с BMP, от \x{10000} до \x{10FFFF}, используйте эквивалентную пару старших и младших суррогатов с синтаксисом регулярного выражения \x{<high>}\x{<low>}, заменяя значения <high> и <low> их точными шестнадцатеричными значениями, используя каждые 4 шестнадцатеричных числа.

Итак, часть, которая допускает отрицательный просмотр, соответствующий одному символу (не "), — это (?!").[\x{DC00}-\x{DFFF}]? где ? в конце я задаю не вопрос, а часть регулярного выражения, которая ищет вторую часть суррогатной пары (если есть вторая часть), а «точка» перед ней обрабатывает как любой символ в BMP, так и первую часть. суррогатной пары. Верно?

anon 22.05.2024 18:41

Да, (?!") ограничивает . от соответствия ", а необязательный [\x{DC00}-\x{DFFF}] соответствует суррогатной части пары.

Wiktor Stribiżew 22.05.2024 22:42

Другие вопросы по теме