2

この 3 つのテキストと 1 つの正規表現があります。(わかりました、HTML ですが、...どうか、それに注目しないでください !!!!)

<h3 class="pubAdTitleBlock "><a href="/it/pubblicazioni/libri/Che-speranza-cè-per-i-morti/1101987030/" title="Che speranza c’è per i morti?">Che speranza c’è per i morti? (volantino N. 16)</a></h3>

<h3 class="pubAdTitleBlock "><a href="/it/pubblicazioni/libri/cosa-insegna-la-bibbia/È-questo-che-Dio-voleva/" title="È questo che Dio voleva?">Cosa insegna realmente la Bibbia?</a></h3>

<h3 class="pubAdTitleBlock">Cantiamo a Geova</h3>

これは正規表現です

regexp = "<h3[^>]*>(<a[^>]*>)?([^<]+)(</a>)?</h3>";

私は3つの3つのグループを持っています:

  • 開始<a>タグ (オプション)
  • テキスト (本のタイトルであり、 regexp の目標です)
  • 終了</a>タグ (オプション)

問題: 2 行目が一致し、3 行目が一致します。最初の番号。なんで ?

一致するコード:

pattern = Pattern.compile(regexp);
matcher = pattern.matcher(fullString);
idx = 0;
while (matcher.find()) {
  ...
}

matcher.find()単純に最初の行をスキップします。これはファイルの最初の行ではなく、10 行目です。最初の例です。

リテラル括弧が問題になる可能性はありますか? 正規表現を修正するには?

編集:試してみました

String regexp = "<h3[^>]*>(.+)</h3>";

しかし、この正規表現も最初の行をスキップします...私は本当に理解できません!!!!

編集2:

私は疑問を持っています: アクセント付きの文字がある場合、問題になる可能性がありますか?

編集3:

ここからデータスクレイピングを試みています: http://www.jw.org/it/pubblicazioni/libri/?contentLanguageFilter=it&sortBy=3

入力ストリームがあり、次のコードを使用して単一の文字列に変換します。

 // copied from http://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string
public static String convertStreamToString(InputStream is) {
    try {
        return new java.util.Scanner(is, "UTF-8").useDelimiter("\\A").next();
    } catch (java.util.NoSuchElementException e) {
        return "";
    }

次に、正規表現を適用しています...

4

2 に答える 2

3

確かではありませんが、おそらくこれはあなたが探しているものです

String data = "<h3 class=\"pubAdTitleBlock \"><a href=\"/it/pubblicazioni/libri/Che-speranza-cè-per-i-morti/1101987030/\" title=\"Che speranza c’è per i morti?\">Che speranza c’è per i morti? (volantino N. 16)</a></h3>"
        + "<h3 class=\"pubAdTitleBlock \"><a href=\"/it/pubblicazioni/libri/cosa-insegna-la-bibbia/È-questo-che-Dio-voleva/\" title=\"È questo che Dio voleva?\">Cosa insegna realmente la Bibbia?</a></h3>"
        + "<h3 class=\"pubAdTitleBlock\">Cantiamo a Geova</h3>";

Pattern pattern = Pattern
        .compile("<h3[^>]*>(?:<a[^>]*>)?([^<]+)(?:</a>)?</h3>");
Matcher matcher = pattern.matcher(data);
while (matcher.find()) 
    System.out.println(matcher.group(1));

出力:

Che speranza c’è per i morti? (volantino N. 16)
Cosa insegna realmente la Bibbia?
Cantiamo a Geova

少し説明:

のようなグループ(?:someregex)は、正規表現メカニズムによってカウントされません。そのおかげで、(?:a)(b)(?:c)(d)グループ(b)は 1 および 2 としてインデックス付けされます(d)

編集1

(正規表現を使用してHTMLを解析することは冒涜的であることは知っていますが、OPがそれを望んでいるため...)解析されたHTMLには、タブ改行マークなど
の空白が含まれていることに言及するのを忘れていました。このようにしてみてください:<h3 >

String data = convertStreamToString(new URL(
        "http://www.jw.org/it/pubblicazioni/libri/?contentLanguageFilter=it&sortBy=3")
        .openStream());

Pattern pattern = Pattern
        .compile("<h3[^>]*>\\s*(?:<a[^>]*>)?([^<]+)(?:</a>)\\s*?</h3>");
Matcher matcher = pattern.matcher(data);
int counter=0;
while (matcher.find())
    System.out.println(++counter +")"+matcher.group(1));

出力:

1)Accostiamoci a Geova
2)Accostiamoci a Geova — caratteri grandi
....
11)Cosa insegna realmente la Bibbia?
12)Cosa insegna realmente la Bibbia? — caratteri grandi
于 2012-10-28T14:52:30.090 に答える
2

Parser や RegExp では使用しないでください。ジェリーを試してみてください。同様に(テストされていません):

Jerry doc = jerry(html);
doc.$("a").each(new JerryFunction() {
    public boolean onNode(Jerry $this, int index) {
        String href = $this.attr("href");
        System.out.println(href);
    }
}

または HTML に適したクエリ言語。外部要件がないため、Java を使用して HTML ディレクトリ リスト内のリンクを解析しようとしています。

(私の回答をコピーして貼り付けました: How do you parse links from html using Java? )

編集:試してください

<h3.*?>(<a.*)?+(.*?)(</a>)?</h3>

グループを取得します(2)

編集2:本のタイトルだけを試してください:

(.*>)?([^<]+?)<.*

編集 3:あなたの正規表現

<h3[^>]*>(<a[^>]*>)?([^<]+)(</a>)?</h3>

私のために働くように見えます。

于 2012-10-28T14:01:42.933 に答える