Как использовать regex flag "w" ("u" in Python) ?

Автор eeigor, 27 февраля 2021, 10:58

0 Пользователи и 1 гость просматривают эту тему.

eeigor

Как-то тут я исследовал тему regex... Работа была продолжена.
Работает всё-всё-всё, как ни странно! Включая и этот набор флагов:  ismx, но кроме w, который тоже присутствует в спецификации.

Осталось невыясненным использование этого флага "w". Вопрос носит чисто теоретический характер.
Вне зависимости от смены локали (ru_Ru, en_US) не получается распознавать "слова" с апострофом, числа с десятичным разделителем (точкой или запятой). А должно?
Для задания флага, если при использовании функции REGEX(), можно просто добавить флаг прямо в выражение: (?w)
Например, для поиска слова с учётом юникода: "(?w)\w+"   или   "(?w:\w+)"

Не могли бы привести примеры, где и когда это может быть полезно, и как это работает? У меня не ищет, и не работает...


Спецификация здесь, в разделе "Flag Options".

w   UREGEX_UWORD  're.U (re.UNICODE) in Python

Controls the behavior of \b in a pattern. If set, word boundaries are found according to the definitions of word found in Unicode UAX 29, Text Boundaries. By default, word boundaries are identified by means of a simple classification of characters as either "word" or "non-word", which approximates traditional regular expression behavior. The results obtained with the two options can be quite different in runs of spaces and other non-word characters.
Перевод:
Управляет поведением \b в шаблоне. Если установлено, границы слова обнаруживаются в соответствии с определениями слова, найденными в Unicode UAX 29, Границы текста. По умолчанию границы слов идентифицируются посредством простой классификации символов как «слово» или «не-слово», что приблизительно соответствует поведению традиционного регулярного выражения. Результаты, полученные с двумя вариантами, могут сильно отличаться в случае пробелов и других символов, не являющихся словами.

Сменить локаль, если в коде...
    Dim oLocale As New com.sun.star.lang.Locale
'   oLocale.Language = "ru": oLocale.Country = "RU"  'by default
   oLocale.Language = "en": oLocale.Country = "US"

   oTextSearch = CreateUnoService("com.sun.star.util.TextSearch")
   oOptions = CreateUnoStruct("com.sun.star.util.SearchOptions")
   oOptions.algorithmType = com.sun.star.util.SearchAlgorithms.REGEXP
   oOptions.Locale = oLocale


Upd1:
Но некоторые комбинированные символы обрабатываются абсолютно правильно и без флага "w".
Вот, к примеру, гла́сные бу́квы с ударе́ниями:
=REGEX("А́ Е́ И́ О́ У́ Ы́ Э́ Ю́ Я́ а́ е́ и́ о́ у́ ы́ э́ ю́ я́";"\b\w+\b";;2)  'вернёт Е́ (с ударением, позиция в списке: 2)
А отключение флага на результат поиска не влияет: "(?-w)\b\w+\b"
Что странно, однако. Возможно, я что-то путаю...

Upd2:
В VBA библиотека VBScript.RegExp предлагает куда более скромные возможности. Когда я её в последний раз использовал, ничего "русского" в плане границ вообще не работало. То есть в локальной среде вместо простого "\w+" надо было использовать "[а-яА-ЯёЁa-zA-Z0-9]+". Почувствуйте разницу!

Upd3:
Пример:
The quick ("brown") fox can't jump 32.3 feet in-the-air, right?
The| |quick| |(||"|brown|"|)| |fox| |can't| |jump| |32.3| |feet| |in|-|the|-|air|,| |right|?|
То, что красным, не воспринимает в качестве одного слова ("\b\w+\b"), а должно бы... "in-the-air" -  три отдельных слова. Как правильно?
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

eeigor

#1
Оффтоп попутно

Синтаксис
REGEX(Text;Expression[;[Replacement][;Flags|Occurrence]])

Flags: Optional. "g" replaces all matches of Expression in Text, not extracted. If there is no match, Text is returned unmodified.

Функция REGEX, на мой взгляд, сконструирована не совсем удачно в плане флага "g" и, вообще, последнего параметра.
При установленном флаге будут заменены все вхождения, если задан параметр замены (Replacement).
Что касается возврата найденного, то если номер вхождения (Occurence) равен нулю, то функция зачем-то возвращает исходную строку (?), а если указан номер вхождения, то вернёт его.

Как обрабатывать ноль, это, конечно, дело вкуса. Но вот почему флаг "g" здесь работает только на замену и не работает на извлечение? Извлекается или первое вхождение, или заданное. Однако, на мой взгляд, при установленном флаге "g" (Global) должные также извлекаться все вхождения (сейчас, если не задан параметр замены, флаг игнорируется). Тогда, если такая функция помещена в ячейку, мы увидели бы первое значение из массива вхождений. Но массив значений можно было бы и объединить в строке через разделитель или поместить в диапазон ячеек, или посчитать и т. д.

Неудачное решение. К тому же, параметр Flags пока обрабатывает только один флаг (при замене). Но ведь их могло бы (и должно) быть больше: "ismwx". И они должны работать не только на замену, но и на извлечение. И извлекать надо любое вхождение. Тогда зачем объединили вместе два разных по смыслу параметра: Flags|Occurrence ? Запятой (точки с запятой) пожалели?
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

eeigor

Опубликовал заявку на улучшения функции. Что я ещё тут могу...
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community