Lua: условное разбиение строки с использованием gmatch

Я пишу плагин для Mushclient в Lua. Mushclient включает в себя мод PCRE, который позволяет мне компилировать регулярные выражения с помощью функции rex.new. Я не уверен, нужно ли мне использовать это, чтобы выполнить то, что я пытаюсь сделать, но я подозреваю, что могу, хотя я бы предпочел этого не делать.

По сути, я хотел бы иметь возможность разбить строку на таблицу, используя разделители "," или "и". Однако в некоторых случаях эти "разделители" появляются внутри элемента, который я хотел бы оставить неразделенным (например, Феликс, Кот). Вот что я сделал до сих пор:

false_separators = {"Felix, the Cat", "orange and tan cat", "black and white cat"}
separators = rex.new(" ?(.+?)(?:,| and )")
local sample_text = "a black and white cat, a tabby cat, a giant cat, Felix, the Cat and an orange and tan cat."
index = 1
matches = {}
separators:gmatch(sample_text, function (m, t) 
    for k, v in pairs(t) do
          print(v)
          table.insert(matches, v)
    end
 end)

Это выведет:

a black
white cat
a tabby cat
a giant cat
Felix
the Cat
an orange

Есть две проблемы с этим. Во-первых, последний пункт не включен. Во-вторых, я не понял, как реализовать мою таблицу false_separators. Мой желаемый результат:

a black and white cat
a tabby cat
a giant cat
Felix, the Cat
an orange and tan cat

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

false_separators = {"Felix, the Cat", "orange and tan cat", "black and white cat"}
local sample_text = "a black and white cat, a tabby cat, a giant cat, Felix, the Cat and an orange and tan cat."

function split_cats(text, false_sep)
    for k, v in ipairs(false_sep) do
        text = text:gsub(v, v:gsub(" ", "_")) -- replace spaces in false separator matches with underscores
    end
    text = text:gsub(" and ", ", "):gsub(", ", ";") -- replace ' and ' (that isn't surrounded by underscores) with a comma, then replace all commas that aren't followed by underscores with a semi-colon. Semi-colon is now the true delimiter
    m = utils.split (text, ";") or {} -- split at semi-colon
    for i, v in ipairs(m) do
        m[i] = v:gsub("_", " ") -- remove underscores
    end
    return m
end

table.foreach(split_cats(sample_text, false_separators), print)

Выход:

1 a black and white cat
2 a tabby cat
3 a giant cat
4 Felix, the Cat
5 an orange and tan cat.

0 ответов

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