regex 如何使用正则表达式提取多条信息?

jv2fixgn  于 2023-06-25  发布在  其他
关注(0)|答案(4)|浏览(108)

我需要从返回的字符串集合中提取多条信息。字符串由许多“字段”组成,例如:

{container="node-exporter", device="/dev/mapper/ubuntu--vg-ubuntu--lv", endpoint="http-metrics", fstype="ext4", instance="172.20.32.10:9100", job="node-exporter", mountpoint="/", namespace="prometheus", pod="prometheus-prometheus-node-exporter-xvz7v", service="prometheus-prometheus-node-exporter"}
{container="node-exporter", device="/dev/mapper/ubuntu--vg-ubuntu--lv", endpoint="http-metrics", fstype="ext4", instance="172.20.32.11:9100", job="node-exporter", mountpoint="/", namespace="prometheus", pod="prometheus-prometheus-node-exporter-w8cqq", service="prometheus-prometheus-node-exporter"}
{container="node-exporter", device="/dev/mapper/ubuntu--vg-ubuntu--lv", endpoint="http-metrics", fstype="ext4", instance="172.20.32.12:9100", job="node-exporter", mountpoint="/", namespace="prometheus", pod="prometheus-prometheus-node-exporter-4wfhq", service="prometheus-prometheus-node-exporter"}
{container="node-exporter", device="/dev/mapper/ubuntu--vg-ubuntu--lv", endpoint="http-metrics", fstype="ext4", instance="172.20.32.13:9100", job="node-exporter", mountpoint="/", namespace="prometheus", pod="prometheus-prometheus-node-exporter-zfskj", service="prometheus-prometheus-node-exporter"}
{container="node-exporter", device="/dev/mapper/ubuntu--vg-ubuntu--lv", endpoint="http-metrics", fstype="ext4", instance="172.20.32.15:9100", job="node-exporter", mountpoint="/", namespace="prometheus", pod="prometheus-prometheus-node-exporter-cllnv", service="prometheus-prometheus-node-exporter"}

在本例中,我想提取fstypeinstancemountpoint字段的标签和值。因此,对于所提供的示例,我最终会得到如下内容:

fstype="ext4" instance="172.20.32.10:9100" mountpoint="/"
fstype="ext4" instance="172.20.32.11:9100" mountpoint="/"
fstype="ext4" instance="172.20.32.12:9100" mountpoint="/"
fstype="ext4" instance="172.20.32.13:9100" mountpoint="/"
fstype="ext4" instance="172.20.32.15:9100" mountpoint="/"

这可以用正则表达式来实现吗?我已经使用RE很长一段时间了,但从来没有这么复杂的东西。如果这个问题的答案是肯定的,我该怎么做?

wpx232ag

wpx232ag1#

这可以通过组和字符串替换来轻松完成。参见this regex

.*(fstype="[^"]*").*?(instance="[^"]*").*?(mountpoint="[^"]*").*

在此替换下:

$1 $2 $3

说明:

我们将创建三个组,它们与您希望具有值的键相匹配。例如第1组:(fstype="[^"]*")。然后,可以通过$1 - $n来引用组。为了使结果字符串只包含组,我们需要使正则表达式匹配整个字符串。因此,正则表达式以.*开始和结束。进一步解释:

  • .*-匹配0到无穷大的非换行符
  • .*?-与上面相同,不同之处在于它匹配'lazy'。这意味着正则表达式试图创建尽可能小的匹配。
  • [^"]*-匹配0到无穷大的字符,不是"
  • (...)-创建一个组,其中的内容来自组内部定义的正则表达式。
    JavaScript小示例:
let input = `
{container="node-exporter", device="/dev/mapper/ubuntu--vg-ubuntu--lv", endpoint="http-metrics", fstype="ext4", instance="172.20.32.10:9100", job="node-exporter", mountpoint="/", namespace="prometheus", pod="prometheus-prometheus-node-exporter-xvz7v", service="prometheus-prometheus-node-exporter"}
{container="node-exporter", device="/dev/mapper/ubuntu--vg-ubuntu--lv", endpoint="http-metrics", fstype="ext4", instance="172.20.32.11:9100", job="node-exporter", mountpoint="/", namespace="prometheus", pod="prometheus-prometheus-node-exporter-w8cqq", service="prometheus-prometheus-node-exporter"}
{container="node-exporter", device="/dev/mapper/ubuntu--vg-ubuntu--lv", endpoint="http-metrics", fstype="ext4", instance="172.20.32.12:9100", job="node-exporter", mountpoint="/", namespace="prometheus", pod="prometheus-prometheus-node-exporter-4wfhq", service="prometheus-prometheus-node-exporter"}
{container="node-exporter", device="/dev/mapper/ubuntu--vg-ubuntu--lv", endpoint="http-metrics", fstype="ext4", instance="172.20.32.13:9100", job="node-exporter", mountpoint="/", namespace="prometheus", pod="prometheus-prometheus-node-exporter-zfskj", service="prometheus-prometheus-node-exporter"}
{container="node-exporter", device="/dev/mapper/ubuntu--vg-ubuntu--lv", endpoint="http-metrics", fstype="ext4", instance="172.20.32.15:9100", job="node-exporter", mountpoint="/", namespace="prometheus", pod="prometheus-prometheus-node-exporter-cllnv", service="prometheus-prometheus-node-exporter"}
`;

const regex = /.*(fstype="[^"]*").*?(instance="[^"]*").*?(mountpoint="[^"]*").*/g;

const newStr = input.replaceAll(regex, "$1 $2 $3");
console.log(newStr);

注意事项:

  • 你需要使用replaceAll(...)函数。否则,只有正则表达式的第一个匹配项将被替换。这导致了正则表达式的一个小的调整。它需要“global”标志,在本例中,该标志由正则表达式末尾的g激活。

备注

根据您需要完成的完整任务,对于给定的数据结构,使用库可能更合理。从你的例子中,我怀疑它是JSON5。根据您使用的编程语言的不同,有许多方法可以使用不同的库。如果你只是在使用一个编辑器(比如VS Code或者Notepad++),你可以使用我在集成搜索功能中提供的正则表达式。

0qx6xfy6

0qx6xfy62#

  • “这可以用正则表达式来完成吗?“*

是的,这叫做“俘虏”。
“如果这个问题的答案是肯定的,我该怎么做?”“*
有许多网站允许正则表达式模式评估和捕获。
许多 Stack Overflow 用户使用的一个流行网站是 regex101.com
您可以使用以下模式。

(fstype|instance|mountpoint)=.(.+?)\"

输出量

fstype, ext4
instance, 172.20.32.10:9100
mountpoint, /
fstype, ext4
instance, 172.20.32.11:9100
mountpoint, /
fstype, ext4
instance, 172.20.32.12:9100
mountpoint, /
fstype, ext4
instance, 172.20.32.13:9100
mountpoint, /
fstype, ext4
instance, 172.20.32.15:9100
mountpoint, /
mlnl4t2r

mlnl4t2r3#

如果已知感兴趣的字段都存在,但它们在字符串中的顺序未知,则可以匹配正则表达式

\b(?<field_name>fstype|instance|mountpoint)=\"(?<field_value>[^"]+)

Demo
如演示所示,对于给定的示例,这将返回三个匹配项,其中包含两个命名捕获组field_namefield_value的内容,如下所示。

field_name     field_value
--------------------------------
fstype         ext4
instance       172.20.32.10:9100
mountpoint     /

此正则表达式具有以下元素。

\b                           # match a word boundary  
(?<field_name>               # begin the named capture group field_name
  fstype|instance|mountpoint # match 'fstype', 'instance' or 'mountpoint'
)                            # end the capture group field_name
=\"                          # match '="'
(?<field_value>              # begin the named capture group field_value
 [^"]+                       # match one or more characters other than double
                             # quotes, as many as possible
)                            # end the capture group field_value

可以通过尝试匹配具有三个正 lookaheads 的正则表达式来测试所有三个字段都存在:

^(?=.*\bfstype=\")(?=.*\binstance=\")(?=.*\bmountpoint=\")

Demo

y1aodyip

y1aodyip4#

要使用正则表达式从字符串集合中提取所需字段,可以执行以下步骤:
构造正则表达式模式:模式应该匹配所需的字段并捕获它们的值。根据您的示例,模式可以构造如下:fstype="([^"]+)”instance="([^"]+)”mountpoint="([^"]+)”
这里,([^"]+)捕获任何非引号字符并将它们分配到相应的组。
编译并应用正则表达式:使用您选择的编程语言中的正则表达式库(例如,Python的re模块)来编译模式并将其应用于集合中的每个字符串。
循环访问集合并提取字段:对于每个字符串,应用正则表达式模式并检索捕获的组。下面是Python中的一个例子:进口环
字符串= [ '{container=“node-exporter”,device="/dev/mapper/ubuntu--vg-ubuntu--lv”,endpoint=“http-metrics”,fstype=“ext4”,instance=“172.20.32.10:9100”,job=“node-exporter”,mountpoint="/",namespace=“prometheus”,pod=“prometheus-prometheus-node-exporter-xvz 7v”,service=“prometheus-prometheus-node-exporter”}',#在此处添加其余字符串]
模式= r 'fstype ="([^"]+)”示例="([^"]+)”挂载点="([^"]+)"'
字符串中的字符串:matches = re.findall(pattern,string)如果匹配:对于匹配中的匹配:fstype,instance,mountpoint = match print(f“fstype="{fstype}”instance="{instance}”mountpoint="{mountpoint}"”)
此代码将遍历每个字符串,应用正则表达式模式,并提取所需字段。然后,它将以所需格式打印提取的字段。
请记住,正则表达式可能很强大,但可能不是所有解析任务的最佳选择。如果字符串的结构变化很大或变得更加复杂,则可能需要考虑提供更高级的模式匹配和提取功能的替代解析技术或库。

相关问题