値をコロンで区切りたいので、分割前のすべての文字に対して正規表現でその文字の補数を使用します。
my $regex
= qr{
( # v- no worry, this matches the first non-space, non-colon
[^\s:]
(?> [^:\n]* # this matches all non-colon chars on the line
[^\s:] # match the last non-space, non-colon, if there
)? # but possibly not there
) # end group
\s* # match any number of whitespace
: # match the colon
\s* # followed by any number of whitespace
( \S # Start second capture with any non space
(?> .* # anything on the same line
\S # ending in a non-space
)? # But, possibly not there at all
| # OR
) # nothing - this gives the second capture as an
# empty string instead of an undef
}x;
while ( <$in> ) {
$hash{ $1 } = $2 if m/$regex/;
}
%hash
次に、次のようになります。
{ '* field' => '100'
, '.Cont.asasd' => ''
, 'H.25 miss here' => 'No'
, Othreaol => 'Value, Other value'
, 'Point->IP' => '0.0.0.0 Port 5060'
, 'Z.15 example' => 'No'
, blahbla => '<Set>'
, scree => '<what>'
}
もちろん、私が考え始めると、/\s+:\s+/
パターンまたは少なくともパターンを確認できる場合は、次のような行/\s{2,}:\s{2,}/
だけの方が簡単かもしれませんsplit
:
while ( <$in> ) {
if ( my ( $k, @v )
= grep {; length } split /\A\s+|\s+\z|(\s+:\s+)/
) {
shift @v; # the first one will be the separator
$hash{ $k } = join( '', @v );
}
}
同じことを行いますが、結果をトリムするためにバックトラックを行う必要はほとんどありません。また、エスケープされたコロンは、スペースで囲まれた裸のコロンでなければならないため、より多くの構文を使用せずに無視します。if ブロックに以下を追加するだけです。
$k =~ s/(?<!\\)(\\\\)*\\:/$1:/g;