带值的正则表达式可选组捕获
Regex Optional Groups Captures with Values
我在使用 Regex 提取不规则数据时遇到困难。我尝试使用 Lookheads,但是当该值不存在时整个匹配 returns false。数据集一直是一致的,直到我到达以 RXX 开头的字符。 RXX 是唯一标识符(组),每组 Rxx 之间的数值是我想要捕获的并将它们分配给组名。
Rxx 值从 R01 到 R15 是随机的,字符串中可以存在 1 到所有 15。
字符串值可能不同于
12*000000000**S304JB01811*8*0*8*4*4*34R0332R152~~~
12*000000000**S304JB01811*9*0*4*3*4*224R023R032R10234R1325~~~
我能够提取值并分配组名,直到到达 Rxx
我的尝试是提取值如下
S304JB0...(?<Total1>[\d]+).(?<Total2>[\d]+).(?<Total3>[\d]+).(?<Total4>[\d]+).(?<Total5>[\d]+).(?<Total6>[\d]+).(?<Total7>[\d]+)
这给了我下面想要的东西
Total1 `1`
Total2 `8`
Total3 `0`
Total4 `8`
Total5 `4`
Total6 `4`
Total7 `34`
下面实现了捕获 R03 值并将其分配给行,但如果字符串中不存在值 R03,则整个匹配 returns false
(?<Row3>(R03)[\d]+)
看看如何使这些正则表达式语句成为可选的,从而允许我return以下
Total1 `1`
Total2 `8`
Total3 `0`
Total4 `8`
Total5 `4`
Total6 `4`
Total7 `34`
Row1 `32`
Row15 `2`
S304JB0...(?<Total1>[\d]+).(?<Total2>[\d]+).(?<Total3>[\d]+).(?<Total4>[\d]+).(?<Total5>[\d]+).(?<Total6>[\d]+).(?<Total7>[\d]+)(?<Row3>(R03)[\d]+)(?<Row4>(R04)[\d]+) ------> (?<Row15>(R15)[\d]+)
感谢您的帮助
-已编辑
感谢乔治的快速回复
输入数据将是
12*000000000**S304JB01811*8*0*8*4*4*34R0332R152~~~
输出将是9个捕获组结果
Group | Result
Total1 = 1
Total2 = 8
Total3 = 0
Total4 = 8
Total5 = 4
Total6 = 4
Total7 = 34
Row1 = 32
Row15 = 2
我的示例在下面与输入和
https://regex101.com/r/wG3aM3/68
希望这有助于澄清事情
D.
我敢肯定这会更容易逐个解析一个字符并存储每个值。
至于正则表达式问题,基本上您想要做的是创建所有组,就像您已经尝试过的那样,但您还希望将它们设为可选,因为可能并非所有组都在那里。
您可以使用如下构造使组可选:
(?:R01(?<Row1>\d+))?
因此您应该添加每一个以获取不同捕获组中的值。请注意,我使用了与组完全相同的构造 (?:non-capturing)
,但它不会创建反向引用。你可以阅读它 here.
编辑: 还有一件事。您正在使用 .
来允许任何定界符。但是,在性能方面,最好使用 \D
之类的东西(数字除外)。在失败的情况下,它为正则表达式引擎节省了很多回溯步骤。
这将是整个表达式,假设 Rxx
组总是有序的。
S304JB0...(?<Total1>\d+)\D(?<Total2>\d+)\D(?<Total3>\d+)\D(?<Total4>\d+)\D(?<Total5>\d+)\D(?<Total6>\d+)\D(?<Total7>\d+)(?:R01(?<Row1>\d+))?(?:R02(?<Row2>\d+))?(?:R03(?<Row3>\d+))?(?:R04(?<Row4>\d+))?(?:R05(?<Row5>\d+))?(?:R06(?<Row6>\d+))?(?:R07(?<Row7>\d+))?(?:R08(?<Row8>\d+))?(?:R09(?<Row9>\d+))?(?:R10(?<Row10>\d+))?(?:R11(?<Row11>\d+))?(?:R12(?<Row12>\d+))?(?:R13(?<Row13>\d+))?(?:R14(?<Row14>\d+))?(?:R15(?<Row15>\d+))?
我在使用 Regex 提取不规则数据时遇到困难。我尝试使用 Lookheads,但是当该值不存在时整个匹配 returns false。数据集一直是一致的,直到我到达以 RXX 开头的字符。 RXX 是唯一标识符(组),每组 Rxx 之间的数值是我想要捕获的并将它们分配给组名。
Rxx 值从 R01 到 R15 是随机的,字符串中可以存在 1 到所有 15。
字符串值可能不同于
12*000000000**S304JB01811*8*0*8*4*4*34R0332R152~~~
12*000000000**S304JB01811*9*0*4*3*4*224R023R032R10234R1325~~~
我能够提取值并分配组名,直到到达 Rxx 我的尝试是提取值如下
S304JB0...(?<Total1>[\d]+).(?<Total2>[\d]+).(?<Total3>[\d]+).(?<Total4>[\d]+).(?<Total5>[\d]+).(?<Total6>[\d]+).(?<Total7>[\d]+)
这给了我下面想要的东西
Total1 `1`
Total2 `8`
Total3 `0`
Total4 `8`
Total5 `4`
Total6 `4`
Total7 `34`
下面实现了捕获 R03 值并将其分配给行,但如果字符串中不存在值 R03,则整个匹配 returns false
(?<Row3>(R03)[\d]+)
看看如何使这些正则表达式语句成为可选的,从而允许我return以下
Total1 `1`
Total2 `8`
Total3 `0`
Total4 `8`
Total5 `4`
Total6 `4`
Total7 `34`
Row1 `32`
Row15 `2`
S304JB0...(?<Total1>[\d]+).(?<Total2>[\d]+).(?<Total3>[\d]+).(?<Total4>[\d]+).(?<Total5>[\d]+).(?<Total6>[\d]+).(?<Total7>[\d]+)(?<Row3>(R03)[\d]+)(?<Row4>(R04)[\d]+) ------> (?<Row15>(R15)[\d]+)
感谢您的帮助
-已编辑 感谢乔治的快速回复
输入数据将是 12*000000000**S304JB01811*8*0*8*4*4*34R0332R152~~~
输出将是9个捕获组结果
Group | Result
Total1 = 1
Total2 = 8
Total3 = 0
Total4 = 8
Total5 = 4
Total6 = 4
Total7 = 34
Row1 = 32
Row15 = 2
我的示例在下面与输入和 https://regex101.com/r/wG3aM3/68
希望这有助于澄清事情 D.
我敢肯定这会更容易逐个解析一个字符并存储每个值。
至于正则表达式问题,基本上您想要做的是创建所有组,就像您已经尝试过的那样,但您还希望将它们设为可选,因为可能并非所有组都在那里。
您可以使用如下构造使组可选:
(?:R01(?<Row1>\d+))?
因此您应该添加每一个以获取不同捕获组中的值。请注意,我使用了与组完全相同的构造 (?:non-capturing)
,但它不会创建反向引用。你可以阅读它 here.
编辑: 还有一件事。您正在使用 .
来允许任何定界符。但是,在性能方面,最好使用 \D
之类的东西(数字除外)。在失败的情况下,它为正则表达式引擎节省了很多回溯步骤。
这将是整个表达式,假设 Rxx
组总是有序的。
S304JB0...(?<Total1>\d+)\D(?<Total2>\d+)\D(?<Total3>\d+)\D(?<Total4>\d+)\D(?<Total5>\d+)\D(?<Total6>\d+)\D(?<Total7>\d+)(?:R01(?<Row1>\d+))?(?:R02(?<Row2>\d+))?(?:R03(?<Row3>\d+))?(?:R04(?<Row4>\d+))?(?:R05(?<Row5>\d+))?(?:R06(?<Row6>\d+))?(?:R07(?<Row7>\d+))?(?:R08(?<Row8>\d+))?(?:R09(?<Row9>\d+))?(?:R10(?<Row10>\d+))?(?:R11(?<Row11>\d+))?(?:R12(?<Row12>\d+))?(?:R13(?<Row13>\d+))?(?:R14(?<Row14>\d+))?(?:R15(?<Row15>\d+))?