Регулярное выражение для шаблона одного необязательного пробела перед китайскими словами в Lua

Я попробовал использовать string.match("Í",'%s?[\u{4e00}-\u{9FFF}]+'), который похож на то, как мы работаем в JS или других. Но он будет соответствовать одному ненужному символу, такому как приведенный выше «Í».

Официальная реализация сопоставления UTF-8 использует eacape \ddd, но \u{XXX}, похоже, не работает , потому что

Средства сопоставления шаблонов Lua работают побайтно.

Временно я использую нестабильный обходной путь, аналогичный utf8.charpattern: string.match("Í",'%s?[\228-\233][%z\1-\191][%z\1-\191]') на основе кодировки utf8 выводится nil и работает для проверки cjk, например '我', хотя у него есть один неправильный диапазон для 2-го байта слева.

Вопрос:

Как решить эту проблему с помощью регулярного выражения?

Можете ли вы установить lrexlib?

Alexander Mashin 11.04.2024 11:49

@AlexanderMashin Спасибо за ваш комментарий. Предпочтительно одно чистое решение Lua без использования одной внешней библиотеки.

An5Drama 11.04.2024 12:10

Не могли бы вы уточнить, чего вы хотите? Я вижу, вы предложили отредактировать мой ответ, добавив break внутри else. Это не то, что вам нужно, если вы просто хотите найти слово (и пробел) в любом месте строки, как это пытается сделать ваш текущий шаблон. Должно ли оно быть в начале (^...), в конце (...$), полном совпадении (^...$)?

Luatic 12.04.2024 02:25

@Luatic Возможно, у меня есть некоторая двусмысленность. %s?[\u{4e00}-\u{9FFF}]+ означает один пробел перед блоком, в котором все слова являются китайскими (без пробелов и других символов. Поэтому я добавляю break). Второй шаблон, похоже, не реализует это, поскольку он основан на байтах.

An5Drama 12.04.2024 03:06

@Luatic Я хочу полное совпадение, а это значит ^%s?[\u{4e00}-\u{9FFF}]+$. Извините за двусмысленность.

An5Drama 12.04.2024 05:01

@An5Drama, окей, в общем, просто проверка. Понятно. Отредактировал свой ответ.

Luatic 13.04.2024 00:29
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
6
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. Шаблоны Lua не являются регулярными выражениями. Регулярные выражения имеют функции, которых нет в шаблонах Lua (например, группировка, возможно, вложенность и выбор), а шаблоны Lua имеют функции, которых нет у регулярных выражений (по крайней мере, в формальном лингвистическом смысле) (например, %b, %1).
  2. Вы правы: шаблоны Lua не работают с «кодовыми точками», они работают с байтами. Вот почему \u{4e00}-\u{9FFF} не работает: Lua видит здесь \228\184\128-\233\191\191, эквивалентный \184\191\228\128-\233, что сильно отличается от того, что вы хотите (в частности, диапазон внезапно меняется от \128 до \233). Я считаю взаимодействие - с многобайтовыми «символами», которые появляются в источниках как одна кодовая точка, немного неуместным.

Поскольку вам нужно чистое решение Lua и учитывая простоту вашего шаблона, возможно решение, созданное вручную:

local codepoints = {}
for _, c in utf8.codes(s) do
    if utf8.char(c):match"^%s$" and codepoints[1] == nil then
        codepoints[1] = c
    elseif c >= 0x4e00 and c <= 0x9FFF then
        table.insert(codepoints, c)
    else
        codepoints = {}
    end
end
local match = utf8.char(table.unpack(codepoints))
if match:match"^%s?$" then match = nil end -- single space or empty string

Обновлено: поскольку вы хотите проверить полное совпадение, это можно упростить:

local match = true
local got_chinese_character = false
for p, c in utf8.codes(s) do
    if c >= 0x4e00 and c <= 0x9FFF then
        got_chinese_character = true
    elseif p > 1 or not utf8.char(c):match"^%s$" then
        -- non-chinese character that is not a leading space
        match = false
        break
    end
end
match = match and got_chinese_character

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