我需要将键和值与下面的文本分开
学生证:0
部门ID = 18432
名称XYZ
Subjects:
Computer Architecture
Advanced Network Security 2
在上面的示例中,学生ID,部门ID和名称是键,0,18432,XYZ是值。键通过:,=或多个空格与值分隔。我试过像
这样的reg ex $line =~ /(([\w\(\)]*\s)*)([=:\s?]?)\s*(\S.*)?$/;
$key = $2;
$colon=$3;
$value = $4;
我面临的问题是确定一个单词是用单个空格分隔的,以及何时用一个以上的空格分隔。
我得到的输出是 line是学生ID:0 key是Student,值是ID:0 虽然我想要密钥是学生ID,值是0.对于像主题:和计算机体系结构这样的行,密钥应该有主题和计算机体系结构。我没有值或冒号后有逻辑,我将字符串附加到上一个键,所以看起来像Subjects = Computer Architecture; Advanced Network Security 2
更新:感谢Ikegami表示我使用了后面的操作员。但我似乎仍有解决问题的方法。
$line=~/^(?: ( [^:=]+ ) (?<!\s\s)\s* [:=]\s*|\s*)(.*)$/x;
所以当我说(?<!\s\s)\s* [:=]\s*|\s*
时我的意思是当有两个以上的空格时,消耗所有的空格,当没有两个连续的空格时,寻找:或=并消耗空格。所以,如果你将下面的行传递给表达式,我不应该得到$ 1 = Name和$ 2 = ABC XYZ?
Name ABC XYZ
我似乎得到的是关键是空的,值是名称ABC XYZ。
答案 0 :(得分:4)
如果
Name Eric Brine
Computer Architecture x86
装置
key: Name Eric value: Brine
key: Computer Architecture value: x86
然后你想要
# Requires 5.10
if (/
^
(?: (?<key> [^:=]+ (?<!\s) ) \s* [:=] \s* (?<val> .* )
| (?<key> .+ (?<!\s) ) \s+ (?<val> \S+ )
)
\s* $
/x) {
my $key = $+{key};
my $val = $+{val};
...
}
或
if (/
^
(?: ( [^:=]+ (?<!\s) ) \s* [:=] \s* ( .* )
| ( .+ (?<!\s) ) \s+ ( \S+ )
)
\s*
( .* )
/x) {
my ($key,$val) = defined($1) ? ($1,$2) : ($3,$4);
...
}
如果
Name Eric Brine
Computer Architecture x86
装置
key: Name value: Eric Brine
key: Computer value: Architecture x86
然后你想要
# Requires 5.10
if (/
^
(?: (?<key> [^:=]+ (?<!\s) ) \s* [:=]
| (?<key> \S+ ) \s
)
\s*
(?<val> .* )
/x) {
my $key = $+{key};
my $val = $+{val};
...
}
或
if (/
^
(?: ( [^:=]+ (?<!\s) ) \s* [:=]
| ( \S+ ) \s
)
\s*
( .* )
/x) {
my $key = defined($1) ? $1 : $2;
my $val = $3;
...
}
请注意,您可以删除所有空格和换行符。例如,最后一个片段可以写成:
if (/^(?:([^:=]+(?<!\s))\s*[:=]|(\S+)\s)\s*(.*)/) {
my $key = defined($1) ? $1 : $2;
my $val = $3;
...
}
答案 1 :(得分:1)
尝试将关键部分指定为两位文本,其间有可选空格;
$line =~ /([\w\(\)]*\s?[\w\(\)]*)\s*([=:]?)\s*(\S.*)?$/;
这应该捕获单字和双字密钥。