Javaでラベルと値のペアを抽出する正規表現
-
23-08-2019 - |
質問
私は次のように複数の行を含むファイルを持っています
Name: Peter
Address: St. Serrano número 12, España
Country: Spain
そして、私はそれはドット、特殊文字を含めることができることを考慮して、正規表現を使用してアドレスを抽出する必要があります(N、C)、AEIOU ...
現在のコードは動作しますが、それは非常に醜い:ます。
Pattern p = Pattern.compile("^(.+?)Address: ([a-zA-Z0-9ñÑçÇáéíóú., ]+)(.+?)$",
Pattern.MULTILINE | Pattern.DOTALL);
Matcher m = p.matcher(content);
if (m.matches()) { ... }
の編集:アドレスフィールドにも複数行に分けることができた。の
Name: Peter
Address: St. Serrano número 12,
Madrid
España
Country: Spain
編集:ファイルも、情報の他の種類が含まれているとして、私は、プロパティオブジェクトまたはYAMLパーサーを使用することはできません。
解決
私はそれだけでなく、Javaの正規表現オブジェクトを知らないが、このパターンのようなものは、それを行います。
^Address:\s*((?:(?!^\w+:).)+)$
複数行及びDOTALLモードがオンであると仮定します。
これは改行文字とコロンが続く単一の単語まで何でも続いアドレスで始まる行を、一致します。
あなたは次のフィールドが「国」である必要があります知っている場合は、は、あなたがこれを簡素化することができ、少します:
^Address:\s*((?:(?!^Country:).)+)$
トリックは、繰り返しグループ内の先読みアサーションです。 '(?!国:)。'ので、我々はただ括弧を非キャプチャでそれを固執:「国の文字列の先頭以外のすべてと一致します(?:...)。と+でそれを定量化し、グループの通常の撮影括弧内のそのすべての
他のヒント
あなたは Properties
のクラスの代わりに、正規表現の中に見たいと思うかもしれません。それはあなたのキーと値のペアを表すために、プレーンテキストまたはXMLファイルを管理するための方法を提供しています。
ですから、あなたの例のファイルを読み込み、そのようにProperties
オブジェクトにロードした後のような値を取得することができます:
Properties properties = new Properties();
properties.load(/* InputStream of your file */);
Assert.assertEquals("Peter", properties.getProperty("Name"));
Assert.assertEquals("St. Serrano número 12, España", properties.getProperty("Address"));
Assert.assertEquals("Spain", properties.getProperty("Country"));
と仮定すると、「コンテンツ」とは、ファイルの内容を含む文字列である、あなたの主な問題は、あなたがmatches()
を使用する必要がありますfind()
を使用しているということです。
Pattern p = Pattern.compile("^Address:\\s*(.*)$", Pattern.MULTILINE);
Matcher m = p.matcher(content);
if ( m.find() )
{
...
}
MULTLINEとDOTALLモードに関する他の回答ではいくつかの混乱があるようです。 MULTILINEは^
と$
アンカーは論理行の、それぞれ、始まりと終わりを一致させることができますものです。 DOTALLドット\n
(改行)のような(ピリオド、フルストップ、何でも)マッチラインの区切り文字と\r
(キャリッジリターン)をすることができます。この正規表現は、をDOTALLモードを使用するを使用MULTILINEモードとの のはならない必要があります。
私は泥の中にスティックであることを意味するものではありませんが、正規表現を使用する必要がありますか?なぜ、あなたの将来の自己(または他の)頭痛を惜しまとないます:
String line = reader.readLine();
while(line != null)
{
line = line.trim();
if(line.startsWith("Address: "))
{
return line.substr("Address: ".length()).trim();
}
line = reader.readLine();
}
return null;
もちろんこれは、同様にビットをパラメータ化することができ、メソッドに入れます。
そうでなければ、私は2番目のプロパティまたはJYAML提案をしたい。
ないのJavaの人が、"Address: (.*)$"
の仕事ではないでしょうか?
編集:Pattern.MULTILINEなし| Pattern.DOTALLオプションは、それがその行にのみ一致する必要があります。
これは、改行が含まれていることはできますか?それは改行を含めることはできません場合は、複数行修飾子を使用する必要はありません、代わりに行うことができます。
Pattern p = Pattern.compile("^Address: (.*)$");
それができるなら、私はあると考えることができ、代替
Pattern p = Pattern.compile("Address: (.*)\nCountry", Pattern.MULTILINE);
はDOTALLがなければ、ドットが改行にマッチしないので、明示的にあなたがについて尋ねた何をすることができ、正規表現で指定することができます。
あなたは間違いなく YAML をチェックアウトする必要があります。
あなたが試みることができる JYAMLするます。
それは多くの言語での実装を持っています。すべてのベスト
はpsの私は YAML :: XS 、それが完璧に動作します。の