7

次のような行をいくつか含むファイルがあります。

Name: Peter
Address: St. Serrano número 12, España
Country: Spain

そして、ドット、特殊文字 (ñ、ç)、áéíóú... を含む可能性があることを考慮して、正規表現を使用してアドレスを抽出する必要があります。

現在のコードは機能しますが、非常に醜いように見えます:.

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

編集: ファイルには他の種類の情報も含まれているため、Properties オブジェクトや YAML パーサーは使用できません。

4

7 に答える 7

6

Javaの正規表現オブジェクトについてはよくわかりませんが、次のパターンのようなものがそれを行います:

^Address:\s*((?:(?!^\w+:).)+)$

multiline および dotall モードがオンであると仮定します。

これは、Address で始まり、改行文字と 1 つの単語の後にコロンが続くまでの任意の行に一致します。

次のフィールドが「国」でなければならないことがわかっている場合は、これを少し単純化できます。

^Address:\s*((?:(?!^Country:).)+)$

トリックは、繰り返しグループの先読みアサーションにあります。'(?!国:)。' 文字列 'Country:' の先頭を除くすべてに一致するため、それを非キャプチャ括弧 (?:...) に入れ、+ で数量化し、そのすべてを通常のキャプチャ括弧でグループ化します。

于 2008-12-26T21:13:16.847 に答える
3

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"));
于 2008-12-25T20:55:46.600 に答える
3

「コンテンツ」がファイルの内容を含む文字列であると仮定すると、主な問題は、使用matches()すべき場所で使用していることですfind()

Pattern p = Pattern.compile("^Address:\\s*(.*)$", Pattern.MULTILINE);
Matcher m = p.matcher(content);
if ( m.find() )
{
  ...
}

MULTLINE および DOTALL モードに関する他の回答には混乱があるようです。MULTILINE は、^$アンカーをそれぞれ論理行の先頭と末尾に一致させるものです。DOTALL を使用すると、ドット (ピリオド、ピリオドなど\n) を (ラインフィード) や\r(キャリッジ リターン) などの行区切り文字に一致させることができます。この正規表現はMULTILINE モードを使用する必要があり、DOTALL モードを使用してはなりません。

于 2008-12-26T04:42:00.233 に答える
1

泥棒になるつもりはありませんが、正規表現を使用する必要がありますか? 将来の自分(または他の人)の頭痛の種を惜しまず、次のことを行ってみませんか。

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;

もちろん、これも少しパラメータ化してメソッドに入れることができます。

それ以外の場合は、Properties または JYaml の提案を支持します。

于 2008-12-26T02:22:30.000 に答える
0

Javaの人ではありませんが、うまくいきません"Address: (.*)$"か?

編集: Pattern.MULTILINE | なし Pattern.DOTALL オプションは、その行でのみ一致する必要があります。

于 2008-12-25T19:54:06.367 に答える
0

改行を含めることはできますか? 改行を含めることができない場合は、複数行修飾子を使用する必要はなく、代わりに使用できます

Pattern p = Pattern.compile("^Address: (.*)$");

可能であれば、私が考えることができる代替手段は

Pattern p = Pattern.compile("Address: (.*)\nCountry", Pattern.MULTILINE);

DOTALL がないと、ドットは改行と一致しないため、正規表現で明示的に指定して、求めたことを実行できます。

于 2008-12-25T19:57:31.523 に答える
0

YAMLをぜひチェックしてください。

JYamlを試すことができます。

何よりも、多くの言語で実装されています。

ps YAML::XSでサンプル テキストを試してみましたが、完全に機能します。

于 2008-12-26T00:21:59.603 に答える