我有一个看起来像这样的字符串 (key":["value","value","value"])
"emailDomains":["google.co.uk","google.com","google.com","google.com","google.co.uk"]
我使用以下正则表达式从字符串中进行选择。 (正则表达式的设置方式不会选择看起来像这样的字符串 "key":[{"key":"value","key":"value"}] )
(?<=:\[").*?(?="])
结果选择:
google.co.uk","google.com","google.com","google.com","google.co.uk
我想删除该选择字符串中的 ",我想知道是否有使用替换命令执行此操作的简单方法。期望的结果...
"emailDomains":["google.co.uk, google.com, google.com, google.com, google.co.uk"]
我该如何解决这个问题?
请您参考如下方法:
如果你的字符串确实有"key":["v1", "v2", ... "vN"]
的形式,你可以拆分出需要改变的部分,用其中的空格替换 ","
,然后重新组合:
my @parts = split / (\["\s* | \s*\"]) /x, $string; #"
$parts[2] =~ s/",\s*"/ /g;
my $processed = join '', @parts;
捕获 split
中分隔符的正则表达式模式,因为在这种情况下分隔符也在返回的列表中,这有助于将字符串重新组合在一起。然后,我们需要更改数组的第三个元素。
在这种方法中,我们必须更改数组中的特定元素,因此如果您的格式有所不同,即使是一点点,这也可能不适合(或仍然可能)适合。
当然应该使用模块将其处理为 JSON。如果不确定格式,如评论中所示,最好尝试确保您拥有 JSON。一旦需求慢慢开始发展,像上面(或下面)那样挑选点点滴滴是一条疯狂之路。
可以在正则表达式中使用相同的方法,这实际上可能有一个优势,可以挖掘并忽略 :
之前的所有内容(使用 split
如果格式与显示的不完全一样,那部分可能会以多个元素结尾,然后会影响一切)
$string =~ s{ :\["\s*\K (.*?) ( "\] ) }{
my $e = $2;
my $n = $1 =~ s/",\s*"/ /gr;
$n.$e
}ex;
此处 /e
修饰符使得替换端被评估为代码,我们在此处执行与上面的 split
相同的操作。关于正则表达式的注释
必须先保存
$2
,因为它会在下一个正则表达式中重置/r
修饰符† 不会改变它的目标而是返回改变后的字符串,它允许我们在只读$1
如果
$2
以及$1
都没有捕获到任何内容,则意味着没有匹配项,结果就是$string
不会改变,悄悄地。因此,如果此替换始终有效,那么您可能需要添加对此类意外数据的处理不需要上面的
$n
,但是可以返回($1 =~ s/",\s*"//gr)。 $e
或者,尝试使用环视
$string =~ s{ (?<=:\[") (.+?) (?="\]) }{ $1 =~ s/",\s*"/ /gr }egx;
什么确实减少了代码量,但以后可能会更棘手。
虽然这是对问题的直接回答,但我认为它最难维护。
† 这个有用的修饰符,用于“非破坏性替换”,出现在 v5.14 中。在早期的 Perl 版本中,我们会复制字符串并在其上运行正则表达式,使用成语
(my $n = $1) =~ s/",\s*"/ /g;
在 lookarounds-example 中我们需要更多
$string =~ s{...}{ (my $n = $1) =~ s/",\s*"/ /g; $n }gr
由于 s/
运算符返回替换次数,而我们需要从 {}
中的整段代码返回 $n
>(替换端),用作替换。