提问人:Jotne 提问时间:10/8/2023 更新时间:10/21/2023 访问量:106
正则表达式从右到左提取
Regex extraction from Right to Left
问:
我有一些数据,我喜欢从右到左提取数据。示例数据
1,4,34
5,15
22
预期输出:
One=34 Two=4 Three=1
One=15 Two=5
One=22
这是我的正则表达式经验所得到的。
(?:(?<three>\d+),)?(?:(?<two>\d+),)?(?<one>\d+)$
但这给出了:
One=34 Two=4 Three=1
One=15 Three=5
One=22
因此,当只有两次提取时,它会失败。有什么好主意吗? PS 我没有任何 revers 工具
答:
^((?:(?<three>\d+),)(?:(?<two>\d+),)|(?:(?<two2>\d+),)?)(?<one>\d+)$
是我能想到的唯一潜在解决方案,但由于捕获组必须都具有不同的名称,因此最终会得到 2 个具有不同名称的“两个”。
评论
您可以将前 2 组作为一个整体设为可选组:
^(?:(?:(?<three>\d+),)?(?<two>\d+),)?(?<one>\d+)$
该模式匹配:
^
字符串的开头(?:
非捕获组(?:(?<three>\d+),)?
(可选)捕获组“三”中的 1+ 位数字并匹配逗号(?<two>\d+),
捕获组“二”中的 1+ 位数字并匹配逗号
)?
关闭非捕获组(?<one>\d+)
捕获组“one”中的 1+ 位数字$
字符串末尾
评论
可以按相反的顺序命名组。
如果您正在寻找相反顺序的匹配,这是一种直接的方法。
这是一个模板正则表达式,可以根据需要进行扩展,并将在字符串中按组升序从最后一个到第一个从左到
右 (LTR) 进行匹配。
这将删除后处理步骤。
例如,这些字符串生成以下匹配数组:
1,4,34 => [34,4,1]
5,15 => [15,5]
22 => [22]
https://regex101.com/r/uo04VM/1
^(?=(?&D_n){0,2}(\d+)$)(?=(?:(?&D_n){0,1}(\d+)(?&n_D)$)?)(?=(?:(\d+)(?&n_D){2}$)?).+$(?(DEFINE)(?<D_n>\d+[^\d\r\n]+)(?<n_D>[^\d\r\n]+\d+))
扩大
^
(?=
(?&D_n){0,2}
( \d+ ) # (1)
$
)
(?=
(?:
(?&D_n){0,1}
( \d+ ) # (2)
(?&n_D) $
)?
)
(?=
(?:
( \d+ ) # (3)
(?&n_D){2} $
)?
)
.+ $
(?(DEFINE)
(?<D_n> \d+ [^\d\r\n]+ ) # (4)
(?<n_D> [^\d\r\n]+ \d+ ) # (5)
)
评论
您想要一个以相反顺序从分隔数据中提取的字段名称变量列表吗?
您可能有多少个条目?三?五?二百七十四?
您是尝试在搜索时(即在 SPL 中您正在编写/运行)还是在 props.conf 中执行此操作?
如果您尝试在搜索时执行此操作,我根本不会尝试使用正则表达式 - 使用 split()(
或 makemv
)和 mvindex()(
带有负索引)来查找您想要的项目:
...
| eval mvlist=split(delimited_field,",")
...
| eval three=mvindex(mvlist,-3)
...
评论
22
2/32
2/1/42
2/1/42
为了避免从右到左使用正则表达式,我找到了一种方法来重新定义字符串。
Sed by it self 似乎限制为 9 个编号的反向引用。
echo "AbCdEfG" | sed -r 's/(.)(.)?(.)?(.)?(.)?(.)?(.)?/\7\6\5\4\3\2\1/'
GfEdCbA
但是 sed splunk 没有这个限制(我也不需要这么多),所以
| makeresults
| eval test="abcdefghijkl"
| rex mode=sed field=test "s/(.)(.)?(.)?(.)?(.)?(.)?(.)?(.)?(.)?(.)?(.)?(.)?/\12\11\10\9\8\7\6\5\4\3\2\1/"
给:test=lkjihgfedcba
然后从左到右使用正则表达式就可以了。
评论