【问题标题】:Regex: Capture Groups and Empty Fields (SWIFT 5 | ICU Regex Engine)正则表达式:捕获组和空字段(SWIFT 5 | ICU 正则表达式引擎)
【发布时间】:2019-11-25 14:01:21
【问题描述】:

我需要一些帮助来纠正我的 RegEx 字符串 - 我有一个文本字符串(一大段 HTML),我需要获取这个 HTML 字符串,然后对其进行模式匹配,以便我拥有 data 987654322@ inside'<div>标签可以提取使用。

我们以<div id=1>的测试用例为例

<div id=1>UID:1currentPartNumber:63222TRES003H1workcenter:VLCSKDcycleTime:98.8curPartCycleTime:63.66partsMade:233curCycleTimeActual:62.4target:291actual:233downtime:97statusReason:lineStatus:Productionefficiency:80.05plusminus:-260curProdTime:7/16/2019 12:28:01 PM</div>

需要注意的是lineStatus可以有值也可以为空,比如statusReason一样

我能够提出一个可以完成大部分工作的正则表达式,但我正在努力处理不存在值的情况。

这是我的尝试:

(
(<div id=(\d|\d\d)>)
(UID:(\d|\d\d))
(currentPartNumber:(.{1,20}))
(workcenter:(.{1,20}))
(cycleTime:(.{1,6}))
(curPartCycleTime:(.{1,6}))
(partsMade:(.{1,6}))
(CycleTimeActual:(.{1,6}))
(target:(.{1,6}))
(actual:(.{1,6}))
(downtime:(.{1,6}))
((statusReason:((?:.)|(.{1,6}))))
((lineStatus:((?:.)|(.{1,6}))))
(Productionefficiency:(.{1,6}))
(plusminus:(.{1,6}))
(curProdTime:(.{1,30}))
)

为了可读性将其拆分。

谢谢,

【问题讨论】:

  • 我认为一个大问题是(currentPartNumber:(.{1,20}) 捕获太多,因为workcenter 出现在第 20 位之前。其他比赛可能也是如此。
  • 感谢您的输入,尽管捕获组不会在另一个开始时停止吗?基本上我这样做{1,20} 的唯一原因是因为另一个闭包组将在匹配后一个闭包组后停止比赛??
  • 嗯,你是对的。我忘记了那个方便的功能。

标签: swift regex icu


【解决方案1】:

尝试正则表达式:((&lt;div id=(\d|\d\d)&gt;)(UID:(\d|\d\d))(currentPartNumber:(.{1,20}))(workcenter:(.{1,20}))(cycleTime:(.{1,6}))(curPartCycleTime:(.{1,6}))(partsMade:(.{1,6}))(CycleTimeActual:(.{1,6}))(target:(.{1,6}))(actual:(.{1,6}))(downtime:(.{1,6}))(statusReason:(.{1,6})?)(lineStatus:(.{1,6})?)(Productionefficiency:(.{1,6}))(plusminus:(.{1,6}))(curProdTime:(.{1,30})))

Demo

警告:You can't Parse HTML with regex

【讨论】:

  • 正则表达式字符串有效 - 意见不是直接来自您链接我的帖子(没有最佳答案,因为它对我没用)“虽然要求正则表达式解析任意 HTML 确实像要求初学者编写操作系统,有时解析一组有限的已知 HTML 是合适的。(插入更多单词).... 正则表达式对我来说工作得很好,而且设置起来非常快。”感谢马特的修复
【解决方案2】:

你们非常非常亲近。

如果你使用:

(
(<div id=\d{1,2}>)
(UID:\d{1,2})
(currentPartNumber:(.{1,20}))
(workcenter:(.{1,20}))
(cycleTime:(.{1,6}))
(curPartCycleTime:(.{1,6}))
(partsMade:(.{1,6}))
(CycleTimeActual:(.{1,6}))
(target:(.{1,6}))
(actual:(.{1,6}))
(downtime:(.{1,6}))
(statusReason:(.{0,6}))
(lineStatus:(.{0,6}))
(Productionefficiency:(.{1,6}))
(plusminus:(.{1,6}))
(curProdTime:(.{1,30}))
(<\/div>)
)

那么$3\n$4\n$6\n$8\n$10\n$12\n$14\n$16\n$18\n$20\n$22\n$24\n$26\n$28\n$30 将是:

UID:1
currentPartNumber:63222TRES003H1
workcenter:VLCSKD
cycleTime:98.8
curPartCycleTime:63.66
partsMade:233cur
CycleTimeActual:62.4
target:291
actual:233
downtime:97
statusReason:
lineStatus:
Productionefficiency:80.05
plusminus:-260
curProdTime:7/16/2019 12:28:01 PM

通过使用(statusReason:(.{0,6}))(lineStatus:(.{0,6})),您可以使 statusReason 和 lineStatus 的值真正成为可选的。

我还简化了启动&lt;div&gt; 和 UID 检测。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 2016-02-10
    • 1970-01-01
    相关资源
    最近更新 更多