Шаблон Lua - как я могу заставить это работать? - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть текстовый файл для обработки, с некоторым примером содержимого следующим образом:

[FCT-FCTVALUEXXXX-IA]
Name=value
Label = value
Zero or more lines of text
Abbr=
Zero or more lines of text
Field A=1
Field B=0
Zero or more lines of text
Hidden=N
[Text-FCT-FCTVALUEXXXX-IA-Note]
One or more note lines
[FCT-FCT-FCTVALUEZ-IE-DETAIL]
Zero or more lines of text
[FCT-FCT-FCTVALUEQ-IA-DETAIL]
Zero or more lines of text
[FCT-_FCTVALUEY-IA]
Name=value
Zero or more lines of text
Label=value
Zero or more lines of text
Field A=1
Abbr=value
Field A=1
Zero or more lines of text
Hidden=N

Мне нужно найти разделы, подобные этому:

[FCT-FCTVALUEXXXX-IA]
Name=value
Label = value
Zero or more lines of text
Abbr=
Zero or more lines of text
Field A=1
Field B=0
Zero or more lines of text
Hidden=N

и извлеките FCT-FCTVALUEXXXX-AA, Name, Label, Abbr, Поле A и B и Hidden, а затем найдите соответствующий раздел (если он существует):

[Text-FCT-FCTVALUEXXXX-IA-Note]
One or more note lines

end извлекает строки заметки как одну строку.

Мне все равно, какие разделы

[FCT-FCT-FCTVALUEZ-IE-DETAIL]
Zero or more lines of text

Могут появиться все три вида разделовв любом месте файла, в том числе в конце, и между разделами не существует предсказуемой взаимосвязи по положению.

Порядок аббревиатур и полей A и B не может быть гарантирован, но они всегда появляются после Name и Label и доСкрытый.

То, что у меня есть:

strParse = "(%[FCT%-.-%-)([IF])([EA])%]%c+Name=(.-)%c.-Label=(.-)%c(.-)Hidden=(%a)%c" --cant pull everything out at once because the order of some fields is not predictable
for id, rt, ft, name, label, detail, hidden in strFacts:gmatch(strParse) do
    --extract details
    abbr=detail:match("Abbr=(.-)%c") --may be blank
    if abbr == nil then abbr = "" end
    FieldA = detail:match("Field A=(%d)")
    FieldB = detail:match("Field B=(%d)")               
    --need to sanitise id which could have a bunch of extraneous material tacked on the front and use it to get the Note
    ident=id:match(".*(%[FCT%-.-%-$)")..rt..ft
    Note = ParseAutonote(ident)  --this is a function to parse the note which I've yet to test so a dummy function returns ""                      
    tblResults[name]={ident, rt, ft, name, label, abbr, FieldA, FieldB, hidden, note}               
end

Большинство из них работает нормально (после многих часов работы над ним), но часть, которая не работает:

(".*(%[FCT%-.-%-$)")

, который должен вывести окончательное вхождение FCT-sometext- вstring id

Моя логика: привязать поиск к концу строки и записать максимально короткую строку, начинающуюся с "[FCT-" и заканчивающуюся "-" в конце строки.

При заданном значении строк текста «[FCT-_ABCD-PDQR-» или «[FCT-XYZ-DETAIL] [FCT-_ABCD-PDQR-» возвращается ноль, когда я хочу вернуть «FCT-_ABCD-»PDQR-».(Обратите внимание, что ABCD, PDQR и т. Д. Могут быть любой длины текста, содержащего альфа, - и _).

1 Ответ

0 голосов
/ 27 декабря 2018

Как вы обнаружили, (".*(%[FCT%-.-%-)$") работает так, как вы хотите, а (".*(%[FCT%-.-%-$)") - нет.$ и ^ являются якорями и должны находиться в конце или в начале шаблона, они не могут появляться в закрытии захвата.

Когда якорные символы появляются где-либо еще в шаблоне, они будут частью искомой строки, исключая случаи, когда ^ используется в наборе для исключения символов, то есть: исключая символы верхнего регистра [^A-Z]

Вот примеры сопоставления с образцом, используя строку примера и образец из вашего вопроса.

print(string.match("[FCT-_ABCD-PDQR-", (".*(%[FCT%-.-%-$)")))  -- initial pattern
> nil
print(string.match("[FCT-_ABCD-PDQR-$", (".*(%[FCT%-.-%-$)"))) -- $ added to end of string
> [FCT-_ABCD-PDQR-$
print(string.match("[FCT-_ABCD-PDQR-", (".*(%[FCT%-.-%-)$")))  -- $ moved to end of pattern
> [FCT-_ABCD-PDQR-
...