Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 如何从这个键值对中提取值?_Regex_Perl - Fatal编程技术网

Regex 如何从这个键值对中提取值?

Regex 如何从这个键值对中提取值?,regex,perl,Regex,Perl,我有一个由“,”分隔的键值对,如下所示。我只需要提取值,不管它是否存在 Category=,userAgent=Mozilla/5.0(Windows NT 6.3;WOW64;Trident/7.0;rv:11.0),比如Gecko,refereringURL=https://www.localhost.com/account/pay?link=credit_card,criteria=InFormCriteria(cc='MZ',tend=123,cd='parts') 我使用了以下代码 w

我有一个由“,”分隔的键值对,如下所示。我只需要提取值,不管它是否存在

Category=,userAgent=Mozilla/5.0(Windows NT 6.3;WOW64;Trident/7.0;rv:11.0),比如Gecko,refereringURL=https://www.localhost.com/account/pay?link=credit_card,criteria=InFormCriteria(cc='MZ',tend=123,cd='parts')

我使用了以下代码

while(<FH>){
    while($_=~m/([^=]+)=([^\s]+,?)/g){
        print $1." ";
    }
    print "\n";
}
while(){
而($)=~m/([^=]+)=([^\s]+,?)/g){
打印$1。”;
}
打印“\n”;
}
我得到以下输出:

,Mozilla/5.0https://www.localhost.com/account/pay?link=credit_card,InFormCriteria(cc='MZ',tend=123,cd='parts')

但是,我需要得到:

类似Gecko的Mozilla/5.0(Windows NT 6.3;WOW64;Trident/7.0;rv:11.0)@@https://www.localhost.com/account/pay?link=credit_card@@InFormCriteria(cc='MZ',tend=123,cd='parts')


我做错了什么?

这比听起来更烦人,因为您的字符串使用了不一致的分隔符。因此,很难用RE进行解析,而且总是不可靠的

模块的存在就是为了做到这一点——正如Wintermute所提到的,它是为解析这种特殊类型的字符串而构建的

如果你真的很难做到这一点,“简单的”分割分隔符方法将不起作用,因为括号中有嵌套的元素。所以我建议-用正则表达式选择键(因为它们总是一个单词,后跟
=

然后,创建一组“sub”正则表达式来解析它

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my $string =
    q{Category=, userAgent=Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko, referringURL=https://www.localhost.com/account/pay?link=credit_card, criteria=InFormCriteria(cc='MZ',tend=123,cd='parts')};

my @keys = ( $string =~ m/(?:^|\s)(\w+)=/g );
my %parsed_thing;

for my $index ( 0 .. $#keys ) {
    my $regex =
          $keys[$index]
        . '=(.*?)[, ]*'
        . ( defined $keys[ $index + 1 ] ? $keys[ $index + 1 ] : '$' );
    print "Using a RE of: ", $regex, "\n";

    my ($value) = ( $string =~ m/$regex/ );
    print "\tGot: $keys[$index] => $value\n";
    $parsed_thing{ $keys[$index] } = $value;
}

print join( '@@', values %parsed_thing ),"\n";
#or
print join( '@@', @parsed_thing{@keys} ),"\n";

您的实际分隔符在我看来更像
(逗号后跟空格)。如果key=value对的值不包含相同的分隔符,使用gawk可以:

gawk '{sub(/^\w+=/, ""); gsub( /, \w+=/, "@@"); print}'
这会将key=部分放在第一个字段中,然后将其他部分转换为
@
。您的示例数据输出如下:

@@Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko@@https://www.localhost.com/account/pay?link=credit_card@@InFormCriteria(cc='MZ'@@123@@'parts')
如果确实需要将空值表示为
,则可以在如下脚本中使用常规gawk/awk:

#!/usr/bin/awk -f

BEGIN {FS=", "; OFS="@@"}

{
    for(i=1; i<=NF; i++) {
        val = substr( $i, index( $i, "=" )+1 )
        if( val=="" ) val="\"\""
        printf "%s%s", val, (i<NF?OFS:"\n")
    }
}

这些解决方案都假定每个字段的形式为key=value,并且没有任何值包含
(逗号后跟空格)。如果后者不是真的,那么您可能希望将日志分隔符(如果可以的话)更改为更清晰的分隔符。或者,如果您可以确定
在值中的不同情况(例如在平衡参数之间),那么您可以在分析主键=值对之前更改这些情况。

这可能是一个XY问题。是否有帮助?实际上它是一个日志文件。HTTP::BrowserDetect与字符串一起工作,因此这不会是一个问题。当iam存储其存储布尔值1或0时,如何将匹配的字符串打印到变量中。请参见编辑。这种散列可以通过各种方式进行操作,以精确地生成您想要的内容。(例如,将“empty”替换为
)(请记住,如果您想要特定的顺序,您可能需要排序。或者您可以边打印边打印)criteria=InFormCriteria(cc='MZ',tend=123,cd='parts')我只需要将键提取为“criteria”,但上面的代码也会生成“tend”和“cd”。事实上,这类场景太多了。以前的正则表达式在这里完全失败了。
""@@Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko@@https://www.localhost.com/account/pay?link=credit_card@@InFormCriteria(cc='MZ',tend=123,cd='parts')