【问题标题】:preg_match_all get the end of the expressionpreg_match_all 获取表达式的结尾
【发布时间】:2020-12-21 09:34:47
【问题描述】:

我有几行:

[3G*2110620000*000A*UD]
[3G*2110620000*000A*LK][3G*2110620000*000A*LK,0,0,100]
[3G*2110620000*000A*LK,100]
[EL*2110620006*000A*LK,0,0],100]]]

结果我需要得到一个数组:

Array(
    [0] => Array
        (
            [Manufacture] => 3G
            [DeviceId] => 2110620000
            [Length] => 000A
            [Command] => UD
        ),
    [1] => Array
        (
            [Manufacture] => 3G
            [DeviceId] => 2110620000
            [Length] => 000A
            [Command] => LK
        ),
    [2] => Array
        (
            [Manufacture] => 3G
            [DeviceId] => 2110620000
            [Length] => 000A
            [Command] => LK
            [Parameters] => 0,0,100
        ),
    [3] => Array
        (
            [Manufacture] => 3G
            [DeviceId] => 2110620000
            [Length] => 000A
            [Command] => LK
            [Parameters] => 100
        ),
    [4] => Array
        (
            [Manufacture] => 3G
            [DeviceId] => 2110620000
            [Length] => 000A
            [Command] => LK
            [Parameters] => 0,0],100]]
        ),
)

每一行可以包含一个或多个命令。

  1. 命令以“[”开头,以“]”结尾。
  2. 命令必须在“[”之后包含制造商名称“3G”或“EL”。
  3. 接下来是“*”分隔符。
  4. 接下来是一个 10 位数字是设备标识符。
  5. 接下来是一个 4 字节的数据包长度。
  6. 接下来是命令名称(可以是任意长度)。
  7. 接下来是“,”分隔符。
  8. 接下来是命令参数(它们可能不存在,它们可以包含任何字符,包括“]”和“[”)。

我正在尝试为这些情况编写一个正则表达式,但我无法突出显示参数。

我试过了

\[(?P<Manufacture>3G|EL)\*(?P<DeviceId>[0-9]{10})\*(?P<Length>[A-Z0-9]{4})\*(?P<Command>.+)[\]|,]{1}(?P<Parameters>.*)\]?

演示:https://regex101.com/r/Iq2Xf4/2

【问题讨论】:

    标签: php regex preg-match-all


    【解决方案1】:

    比赛应该以] 结束,但Parameters 组也可以包含[]

    一种选择是匹配尽可能少的字符,直到到达以 3G 或 EL 开头或右方括号后的字符串结尾的另一部分。

    \[(?P<Manufacture>3G|EL)\*(?P<DeviceId>[0-9]{10})\*(?P<Length>[A-Z0-9]{4})\*(?P<Command>[^[,\r\n]*)(?:,(?P<Parameters>.*?(?=](?:\[(?:3G|EL)|$))))?]
    

    说明

    • \[匹配[
    • (?P&lt;Manufacture&gt;3G|EL)\* 命名组 Manufacture 匹配 3GEL*
    • (?P&lt;DeviceId&gt;[0-9]{10})\* 命名组 DeviceId 匹配 10 位数字和 *
    • (?P&lt;Length&gt;[A-Z0-9]{4})\* 命名组 Length 匹配 4 次 A-Z 或 0-9 之一
    • (?P&lt;Command&gt;[^[,\r\n]*) 命名组 Command 匹配 [ 后跟除 [ , 或换行符以外的任何字符
    • (?:非捕获组
      • ,(?P&lt;Parameters&gt;.*? 匹配 , 后跟组中尽可能少的任何字符 Parameters
      • (?=](?:\[(?:3G|EL)|$)) 肯定前瞻断言右边的内容是 [3G[EL 或字符串的结尾
    • )?关闭非捕获组并使其可选
    • ]比赛结束]

    Regex demo

    【讨论】:

      猜你喜欢
      • 2012-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-23
      相关资源
      最近更新 更多