perl regex在括号之间省略文本但在关键字后保留小数

时间:2014-06-04 13:57:47

标签: regex string perl string-matching

我很难找到正则表达式, 我有字符串

my $str = "(1:[&a={1sa},s=3,keyword=0.1,qwsz={a}]:0.1)[s=2;p]:2:[s=3, keyword=9.23]";

并且想要丢弃方括号之间的任何内容,除了在子串keyword=之后出现的十进制数。结果字符串应如下所示:

"(1:0.1):2:9.23"

我尝试使用匹配我不想要的模式\[.+?keyword=([0-9]+\.[0-9]+).+?],我在在线正则表达式测试中测试过。但是

my $str =~ s/\[.+?keyword=([0-9]+\.[0-9]+).+?]//g;

不起作用。

3 个答案:

答案 0 :(得分:2)

这使用可执行的替换字符串。所有序列如[...]都会被keyword之后的值替换(如果它出现在序列中),或者替换为空字符串(如果它不出现。)

use strict;
use warings;
my $str = '(1:[&a={1sa},s=3,keyword=0.1,qwsz={a}]:0.1)[s=2;p]:2:[s=3, keyword=9.23]';

$str =~ s{ \[ ( [^[\]]* ) \] }{
  $1 =~ /keyword=([\d.]+)/ ? $1 : '';
}egx;

print $str;

<强>输出

(1:0.1:0.1):2:9.23

答案 1 :(得分:1)

将以下正则表达式选择替换为空字符串

\[((?!\])(?<!keyword=).)*(\]|(?=\d+\.\d+))|,.*?\]|\]

<强>解释

\[((?!\])(?<!keyword=).)*(\]|(?=\d+\.\d+)) // Starts with a [, not followed by ], not preceded by keyword=, including all characters till a ] or decimals are encountered
|,.*?\]                                    // OR a comma followed by anything till the first occurance of a ]
|\]                                        // OR a ]

例如

#!/usr/bin/perl

my $str = "(1:[&a={1sa},s=3,keyword=0.1,qwsz={a}]:0.1)[s=2;p]:2:[s=3, keyword=9.23]";
$str =~ s/\[((?!\])(?<!keyword=).)*(\]|(?=\d+\.\d+))|,.*?\]|\]//g;
print "$str";

输出

(1:0.1:0.1):2:9.23

答案 2 :(得分:0)

假设每个方括号组只有一个keyword,您可以使用

$str =~ s/\[[^]]*?keyword=([0-9.]+)[^]]*]|\[[^]]*]/$1/g;

查看demo here

<强>解释

我们希望匹配所有[...]并将其替换为捕获组的内容,只有在括号内有keyword时才会为空:

  \[                 # first case: the [...] contains keyword. We match `[`
  [^]]*?             # followed by anything except a `]`, until the first...
  keyword=([0-9.]+)  # ... keyword pattern. We capture the wanted number
  [^]]*]             # and we match the rest of the [...] pattern.
|                    # OR
  \[[^]]*]           # second case: there's no keyword. We match, but 
                     # don't capture anything.