【问题标题】:Lua pattern -- how can I get this to work?Lua 模式——我怎样才能让它工作?
【发布时间】:2019-05-25 14:47:48
【问题描述】:

我有一个文本文件要处理,示例内容如下:

[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、Field A和B以及Hidden,然后找到对应的section(如果存在的话):

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

结束将注释行提取为单个字符串。

我不关心这些部分

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

这三种类型的部分都可以出现在文件中的任何位置,包括末尾,并且部分之间的位置没有可预测的关系。

不能保证 Abbr 和字段 A 和 B 的顺序,但它们总是出现在名称和标签之后,隐藏之前。

到目前为止我所拥有的:

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- 在字符串 id 中

我的逻辑:将搜索锚定到字符串的末尾,并在字符串末尾捕获以“[FCT-”开头并以“-”结尾的最短可能字符串。

给定值“[FCT-_ABCD-PDQR-”或 “[FCT-XYZ-DETAIL] 文本行 [FCT-_ABCD-PDQR-” 当我希望它返回“FCT-_ABCD-PDQR-”时它返回 nil。 (注意 ABCD、PDQR 等可以是包含 Alpha、- 和 _ 的任意长度的文本。

【问题讨论】:

  • (".*(%[FCT%-.-%-)$") 有效,但我不明白为什么。
  • $ 必须位于模式字符串的末尾以具有magic 的含义,如果您将$ 放在) 之前,它认为您想要一个具有实际@ 的字符串987654332@ char 在里面
  • @Nifim Ah-ha,感谢您的解释。
  • 这是一个很好的 lua 模式“备忘单”资源:fhug.org.uk/wiki/wiki/…
  • 是的……有趣的是,它的数据与我正在解析的程序相关联。但是,我认为我的 $ 确实在字符串的末尾(除了捕获闭包)。

标签: lua lua-patterns


【解决方案1】:

当您发现自己 (".*(%[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-

【讨论】:

    猜你喜欢
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-01-22
    • 2011-04-26
    • 1970-01-01
    • 2021-09-27
    • 2018-03-12
    • 2011-09-27
    相关资源
    最近更新 更多