正则表达式获取类似 xpath 的字符串中的每个项目,每个下标作为一个组
Regex to get each item in an xpath-like string, with each subscript as a group
我想采用类似 xpath 的字符串,例如:
a.b.c[2].d[123].e1[4].f88[5]
并将每个路径部分作为一个匹配项,将每个下标(“数组索引”)作为一个组,如下所示:
match 1: a
match 2: b
match 3: c, group 1: 123
match 4: e1, group 1: 4,
match 5: f88, group 1: 5
我尝试了以下方法(无效):
[^.]+(?:\[)*([0-9]+)*(?:\])*
根据我的理解,这个正则表达式的意思是:
- 首先,匹配除点以外的所有字符
- 然后,检查(但不要捕获)左方括号 - 它可能出现 0 次到无限次。
- 然后,检查任何数字,长度从 1 到无限 - 并作为一个组捕获。
- 然后,为右方括号再次执行 2。
但是没用。
我怎样才能让它发挥作用?
[^.]+(?:\[)*([0-9]+)*(?:\])*
“但它不起作用” 因为 +
是 greedy 并且 consumes 点之前的所有字符。此外,每个下标是整体可选的,而不是逐个部分。
应用这些标准,这个表达式确实有效:
([^.\[]+)(?:\[(\d+)\])?
您试过的模式:
您尝试的模式匹配太多,因为 negated character class [^.]+
匹配除点以外的任何字符 1 次或多次,也可以匹配方括号。
请注意,此表示法 (?:\[)*
与 \[*
相同,并且匹配 0 次或多次左方括号
如果 \G
锚点 is supported,并且您只想从字符串的开头匹配示例字符串,您可以为您想要的数据使用 2 个捕获组,并匹配中间的点和方括号。
\G([^\][.\s]+)(?:\[(\d+)\])?\.?
模式匹配:
\G
断言位置在上一个匹配的末尾,或者在字符串的开头
([^\][.\s]+)
捕获 组 1,匹配除 ]
[
.
以外的 1+ 个字符或空白字符 (因为示例字符串中似乎没有任何空格)
(?:\[(\d+)\])?
可选匹配捕获 组 2 在匹配的方括号之间
\.?
匹配一个可选的点以继续对 \G
anchor 的连续匹配
如果字符串末尾不能有点,并且必须至少有 1 个点,您可以先从字符串的开头断言整个格式:
(?:^(?=[^.]+(?:\.[^.]+)+$)|\G(?!^))\.?([^\][.]+)(?:\[(\d+)\])?
我想采用类似 xpath 的字符串,例如:
a.b.c[2].d[123].e1[4].f88[5]
并将每个路径部分作为一个匹配项,将每个下标(“数组索引”)作为一个组,如下所示:
match 1: a
match 2: b
match 3: c, group 1: 123
match 4: e1, group 1: 4,
match 5: f88, group 1: 5
我尝试了以下方法(无效):
[^.]+(?:\[)*([0-9]+)*(?:\])*
根据我的理解,这个正则表达式的意思是:
- 首先,匹配除点以外的所有字符
- 然后,检查(但不要捕获)左方括号 - 它可能出现 0 次到无限次。
- 然后,检查任何数字,长度从 1 到无限 - 并作为一个组捕获。
- 然后,为右方括号再次执行 2。
但是没用。
我怎样才能让它发挥作用?
[^.]+(?:\[)*([0-9]+)*(?:\])*
“但它不起作用” 因为 +
是 greedy 并且 consumes 点之前的所有字符。此外,每个下标是整体可选的,而不是逐个部分。
应用这些标准,这个表达式确实有效:
([^.\[]+)(?:\[(\d+)\])?
您试过的模式:
您尝试的模式匹配太多,因为 negated character class
[^.]+
匹配除点以外的任何字符 1 次或多次,也可以匹配方括号。请注意,此表示法
(?:\[)*
与\[*
相同,并且匹配 0 次或多次左方括号
如果 \G
锚点 is supported,并且您只想从字符串的开头匹配示例字符串,您可以为您想要的数据使用 2 个捕获组,并匹配中间的点和方括号。
\G([^\][.\s]+)(?:\[(\d+)\])?\.?
模式匹配:
\G
断言位置在上一个匹配的末尾,或者在字符串的开头([^\][.\s]+)
捕获 组 1,匹配除]
[
.
以外的 1+ 个字符或空白字符 (因为示例字符串中似乎没有任何空格)(?:\[(\d+)\])?
可选匹配捕获 组 2 在匹配的方括号之间\.?
匹配一个可选的点以继续对\G
anchor 的连续匹配
如果字符串末尾不能有点,并且必须至少有 1 个点,您可以先从字符串的开头断言整个格式:
(?:^(?=[^.]+(?:\.[^.]+)+$)|\G(?!^))\.?([^\][.]+)(?:\[(\d+)\])?