Я попробовал использовать 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-го байта слева.
Вопрос:
Как решить эту проблему с помощью регулярного выражения?
@AlexanderMashin Спасибо за ваш комментарий. Предпочтительно одно чистое решение Lua без использования одной внешней библиотеки.
Не могли бы вы уточнить, чего вы хотите? Я вижу, вы предложили отредактировать мой ответ, добавив break
внутри else
. Это не то, что вам нужно, если вы просто хотите найти слово (и пробел) в любом месте строки, как это пытается сделать ваш текущий шаблон. Должно ли оно быть в начале (^...
), в конце (...$
), полном совпадении (^...$
)?
@Luatic Возможно, у меня есть некоторая двусмысленность. %s?[\u{4e00}-\u{9FFF}]+
означает один пробел перед блоком, в котором все слова являются китайскими (без пробелов и других символов. Поэтому я добавляю break
). Второй шаблон, похоже, не реализует это, поскольку он основан на байтах.
@Luatic Я хочу полное совпадение, а это значит ^%s?[\u{4e00}-\u{9FFF}]+$
. Извините за двусмысленность.
@An5Drama, окей, в общем, просто проверка. Понятно. Отредактировал свой ответ.
%b
, %1
).\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
Можете ли вы установить lrexlib?