我需要从以下字符串中提取message属性(即我想提取字符串“test”在文件中出现4次。)。
severity="warning" message="The String "test" appears 4 times in the file." source="com.puppycrawl.tools.checkstyle.checks.coding.MultipleStringLiteralsCheck"
我已尝试使用正则表达式message="([^"]*)"
,但这会在第一个出现时停止。The String
在这种情况下会返回。
有没有办法忽略message属性中的内部引号并捕获整个属性?
答案 0 :(得分:1)
如果属性始终按此顺序排列,即source
跟message
之后,您可能会尝试使其更加健壮
message="(.*?)"\s+source="
如果消息中出现source=
,这将会中断。
答案 1 :(得分:1)
如果我们可以假设键总是由字母数字或下划线符号(\w+
组成),后跟=
,并且vlaues不包含模式,您可以使用带有点.*?
的延迟量词,并使用正lookehead检查尾随边界。因此,作为快速而肮脏的一次性修复,您可以使用
message="(.*?)"(?=\s+\w+=|$)
请参阅regex demo
请注意,.
默认情况下与换行符号不匹配,您需要/s
修饰符。
您需要修改输入。
答案 2 :(得分:1)
此解决方案不断从字符串中提取字符,直到遇到source=
这样的新标签。所有参数值都存储在哈希%params
中,因此message
的值仅为$params{message}
我已经使用Data::Dump
仅在解析字符串后显示完整的哈希内容
use strict;
use warnings 'all';
use feature 'say';
my $str = 'severity="warning" message="The String "test" appears 4 times in the file." source="com.puppycrawl.tools.checkstyle.checks.coding.MultipleStringLiteralsCheck"';
my %params;
while ( $str =~ / (\w+) \s* = \s* " ( (?: . (?! \w+ \s* = ) )* ) " /gsx ) {
$params{$1} = $2;
}
say $params{message};
use Data::Dump;
dd \%params;
The String "test" appears 4 times in the file.
{
message => "The String \"test\" appears 4 times in the file.",
severity => "warning",
source => "com.puppycrawl.tools.checkstyle.checks.coding.MultipleStringLiteralsCheck",
}