3

以下のようなテキストからキーと値を分離する必要があります

学生ID:0
部門ID=18432
名前XYZ

Subjects:
Computer Architecture
Advanced Network Security 2

上記の例では、Student ID、Department ID、およびNameがキーであり、0,18432、XYZが値です。キーは、:、=または複数のスペースで値から区切られます。などの正規表現を試しました

    $line =~ /(([\w\(\)]*\s)*)([=:\s?]?)\s*(\S.*)?$/;
    $key   = $2;
    $colon=$3;
    $value = $4;

私が直面している問題は、単語が1つのスペースで区切られている場合と、複数のスペースで区切られている場合を特定することです。

私が取得する出力は、行がStudent ID:0キーがStudent、値がID:0で、キーが必要な場合はStudent ID、値が0です。Subjects:やComputer Architectureのような行の場合、キーにはSubjectsとComputerArchitectureが必要です。後で値やコロンがないときにロジックがあります。前のキーに文字列を追加して、Subjects = Computer Architecture; Advanced NetworkSecurity2のようになります。

更新:ルックビハインドオペレーターを使用していることを示してくれた池上に感謝します。しかし、私はまだそれを解決するのに問題があるようです。

$line=~/^(?: ( [^:=]+ ) (?<!\s\s)\s* [:=]\s*|\s*)(.*)$/x;

つまり(?<!\s\s)\s* [:=]\s*|\s*、2つ以上のスペースがある場合はすべてのスペースを消費し、2つの連続するスペースがない場合は、:または=を探してスペースを消費します。したがって、以下の行を式に渡すと、$ 1=Nameおよび$2= ABC XYZを取得する必要がありますか?

Name         ABC XYZ

私が取得しているように見えるのは、キーが空で、値がNameABCXYZです。

4

2 に答える 2

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;
   ...
}
于 2012-10-03T18:53:55.750 に答える
1

キー部分を2ビットのテキストとして指定し、その間にオプションのスペースを入れてみてください。

$line =~ /([\w\(\)]*\s?[\w\(\)]*)\s*([=:]?)\s*(\S.*)?$/;

これにより、1ワードと2ワードの両方のキーがキャプチャされます。

于 2012-10-03T18:50:31.877 に答える