regex 从右到左的正则表达式提取

kninwzqo  于 2023-10-22  发布在  其他
关注(0)|答案(5)|浏览(138)

我有一些数据,我喜欢从右到左提取数据。样本数据

1,4,34
5,15
22

预期输出:

One=34  Two=4  Three=1
One=15  Two=5
One=22

这是我对regex的经验。

(?:(?<three>\d+),)?(?:(?<two>\d+),)?(?<one>\d+)$

但这给出了:

One=34  Two=4  Three=1
One=15  Three=5
One=22

所以当只有两个提取时它失败了。有什么好主意吗?PS我没有任何反转工具

daupos2t

daupos2t1#

您可以将前两个组作为一个整体设置为可选:

^(?:(?:(?<three>\d+),)?(?<two>\d+),)?(?<one>\d+)$

模式匹配:

  • ^字符串开头
  • (?:非捕获组
  • (?:(?<three>\d+),)?可选地捕获组“three”中的1+数字并匹配逗号
  • (?<two>\d+),捕获“two”组中的1+位数并匹配逗号
  • )?关闭非捕获组
  • (?<one>\d+)捕获“一”组中的1+位数
  • $字符串结尾

Regex demo

ybzsozfc

ybzsozfc2#

^((?:(?<three>\d+),)(?:(?<two>\d+),)|(?:(?<two2>\d+),)?)(?<one>\d+)$是我能想到的唯一可能的解决方案,但由于捕获组必须具有不同的名称,因此最终会有两个名称不同的“two”。

bwntbbo3

bwntbbo33#

按相反的顺序排列组是可以的。
如果你正在寻找相反顺序的匹配,这是一个直接的方法。
这是一个模板正则表达式,可以根据需要展开,并将左匹配到
right(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)
)
sczxawaw

sczxawaw4#

你想要一个变量列表字段 * 名称 * 提取分隔数据在相反的顺序?
你能有多少个条目?三个五个二百七十四?
你是想在搜索时(即在SPL中你正在编写/运行),还是在props.conf中这样做?
如果你在搜索时尝试这样做,我不会尝试使用正则表达式-使用split()(或makemv)和mvindex()(带负索引)来查找你想要的项目:

...
| eval mvlist=split(delimited_field,",")
...
| eval three=mvindex(mvlist,-3)
...
clj7thdc

clj7thdc5#

为了避免从右向左使用正则表达式,我找到了一种方法来反转字符串。
Sed本身似乎有一个限制,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
然后从左到右使用正则表达式就可以了。

相关问题