0

いくつかの特殊文字を含む文字列があります。目的は、各行 (, で区切られた) の String[] を取得することです /n と , を使用できる特殊文字 " があります

For example Main String
Alpha,Beta,Gama,"23-5-2013,TOM",TOTO,"Julie, KameL
Titi",God," timmy, tomy,tony,
tini".

"" に /n があることがわかります。

これを解析するのを手伝ってくれませんか。

ありがとう

__ 詳しい説明

Main Sting では、これらを分離する必要があります

Here Alpha
Beta
Gama
23-5-2013,TOM
TOTO
Julie,KameL,Titi
God
timmy, tomy,tony,tini

問題は : Julie、KameL、Titi の改行 /n または
KameL と Titi の間 timmy、tomy、tony、tini の同様の問題に改行 /n または
tony と tini の間にあります。


new this text is in file (必須の行ごとの読み取り)

Alpha,Beta Charli,Delta,Delta Echo ,Frank George,Henry
1234-5,"Ida, John
 ", 25/11/1964, 15/12/1964,"40,000,000.00",0.0975,2,"King, Lincoln 
 ",Mary / New York,123456
12543-01,"Ocean, Peter

出力「これを削除したい」

Alpha
Beta Charli
Delta
Delta Echo
Frank George
Henry
1234-5
Ida
John
"
25/11/1964
15/12/1964
40,000,000.00
0.0975
2
King
Lincoln
"
Mary / New York
123456
12543-01
Ocean
Peter
4

4 に答える 4

3

説明

データ部分を再構築するために追加の処理を必要としない、Java パーサーでテストされた汎用正規表現の次の PowerShell の例を検討してください。最初に一致するグループは引用符に一致し、それを一致の最後まで運ぶので、引用符の間の値全体を確実に取得できますが、引用符は含まれません。また、引用符で区切られた部分文字列が埋め込まれていない限り、コンマもキャプチャしません。

(?:^|,\s{0,})(["]?)\s{0,}((?:.|\n|\r)*?)\1(?=[,]\s{0,}|$)

$Matches = @()
$String = 'Alpha,Beta,Gama,"23-5-2013,TOM",TOTO,"Julie, KameL\n
Titi",God,"timmy, \n
tomy,tony,tini"'
$Regex = '(?:^|,\s{0,})(["]?)\s{0,}((?:.|\n|\r)*?)\1(?=[,]\s{0,}|$)'

Write-Host start with 
write-host $String
Write-Host
Write-Host found
([regex]"(?i)(?m)$Regex").matches($String) | foreach {
    write-host "key at $($_.Groups[1].Index) = '$($_.Groups[1].Value)'`t= value at $($_.Groups[2].Index) = '$($_.Groups[2].Value)'"
    } # next match

収量

start with
Alpha,Beta,Gama,"23-5-2013,TOM",TOTO,"Julie, KameL\n
Titi",God,"timmy, \n
tomy,tony,tini"

found
key at 0 = ''   = value at 0 = 'Alpha'
key at 6 = ''   = value at 6 = 'Beta'
key at 11 = ''  = value at 11 = 'Gama'
key at 16 = '"' = value at 17 = '23-5-2013,TOM'
key at 32 = ''  = value at 32 = 'TOTO'
key at 37 = '"' = value at 38 = 'Julie, KameL\n
Titi'
key at 60 = ''  = value at 60 = 'God'
key at 64 = '"' = value at 65 = 'timmy, \n
tomy,tony,tini'

概要

ここに画像の説明を入力

  • (?:非キャプチャ グループの開始
  • ^文字列の開始が必要
  • |また
  • ,\s{0,}コンマの後に任意の数の空白が続く
  • )非キャプチャ グループを閉じる
  • (キャプチャ グループ 1 を開始
  • ["]?存在する場合は引用を消費します。他の文字を含めてから引用したい場合に備えて、このようにするのが好きです
  • )キャプチャ グループ 1 を閉じる
  • \s{0,}存在する場合はスペースを消費します。これは、後で値をトリミングする必要がないことを意味します
  • (キャプチャ グループ 2 を開始
  • (?:.|\n|\r)*?貪欲でない、改行を含むすべての文字をキャプチャする
  • )キャプチャ グループ 2 を閉じる
  • \1引用符があった場合はグループ 1 に格納されるため、引用符があった場合はここでそれを必要とします
  • (?=ゼロ アサーション ルックアヘッドを開始
  • [,]\s{0,}カンマの後にオプションの空白が必要です
  • |また
  • $文字列の終わり
  • )ゼロ アサーションを閉じる
于 2013-05-14T05:38:32.410 に答える
1

これを試して:

String source = "Alpha,Beta,Gama,\"23-5-2013,TOM\",TOTO,\"Julie, KameL\n"
              + "Titi\",God,\" timmy, tomy,tony,\n"
              + "tini\".";

Pattern p = Pattern.compile("(([^\"][^,]*)|\"([^\"]*)\"),?");
Matcher m = p.matcher(source);

while(m.find())
{
    if(m.group(2) != null)
        System.out.println( m.group(2).replace("\n", "") );
    else if(m.group(3) != null)
        System.out.println( m.group(3).replace("\n", "") );
}

引用符なしの文字列に一致する場合、結果はグループ 2 に返されます。引用符付きの文字列はグループ 3 に返されます。したがって、while ブロックで区別する必要がありました。もっときれいな方法が見つかるかもしれません。

出力:
Alpha
Beta
Gama
23-5-2013,TOM
TOTO
Julie, KameLTiti
God
timmy, tomy,tony,tini
.

于 2013-05-14T01:01:15.677 に答える
0

CSV を解析するためのまともな Java 互換正規表現については、この関連する回答を参照してください。

以下を認識します。

  • 改行 (値の後または引用符内の値)
  • 次のようなエスケープされた二重引用符を含む引用符付きの値""this""

つまり、次のパターンを使用します。(?:,|\n|^)("(?:(?:"")*[^"]*)*"|[^",\n]*|(?:\n|$))

次に、各 Matchergroup(1)find()ループで収集します。


注:私が発見した「まともな」正規表現についてこの回答をここに投稿しましたが、検索する人々を救うためだけに、決して堅牢ではありません。ユーザー「fgv」によるこの回答にはまだ同意します。CSVパーサーが望ましいです。

于 2018-08-27T15:27:57.387 に答える