4

こんにちは、私は正規表現の世界では非常に新しいです。Java のテスト文字列のタイムスタンプ、場所、および「id_str」フィールドを抽出したいと思います。

20110302140010915|{"user":{"is_translator":false,"show_all_inline_media":false,"following":null,"geo_enabled":true,"profile_background_image_url":"http:\/\/a3.twimg.com\/a\/1298918947\/images\/themes\/theme1\/bg.png","listed_count":0,"favourites_count":2,"verified":false,"time_zone":"Mountain Time (US & Canada)","profile_text_color":"333333","contributors_enabled":false,"statuses_count":152,"profile_sidebar_fill_color":"DDEEF6","id_str":"207356721","profile_background_tile":false,"friends_count":14,"followers_count":13,"created_at":"Mon Oct 25 04:05:43 +0000 2010","description":null,"profile_link_color":"0084B4","location":"WaKeeney, KS","profile_sidebar_border_color":"C0DEED",

私はこれを試しました

(\d*).*?"id_str":"(\d*)",.*"location":"([^"]*)"

遅延量指定子 (regexbuddy で 3000 ステップ) を使用すると、多くのバックトラックがあり.*?ますが、アンカー "id_str" と "location" の間の文字数は常に同じではありません。また、文字列に場所が見つからない場合、壊滅的な事態になる可能性があります。

1) 不要な後戻りを避けるにはどうすればよいですか?

2) 一致しない文字列を見つける方が速いですか?

ありがとう。

4

2 に答える 2

5

これは JSON のように見えますが、この方法で解析するのは非常に簡単です。

String[] input = inputStr.split("|", 2);
System.out.println("Timestamp: " + input[0]); // 20110302140010915

JSONObject user = new JSONObject(input[1]).getJSONObject("user");

System.out.println ("ID: " + user.getString("id_str")); // 207356721
System.out.println ("Location: " + user.getString("location")); // WaKeeney, KS

参照:
JSON Java API ドキュメント

于 2013-06-22T21:32:30.513 に答える
3

代わりにこれを試すことができます:

(\d*+)(?>[^"]++|"(?!id_str":))+"id_str":"(\d*+)",(?>[^"]++|"(?!location":))+"location":"([^"]*+)"

ここでの考え方は、所有量指定子と文字クラスが制限されたアトミック グループのみを使用してバックトラックを可能な限り排除することです (最後のキャプチャ グループで行ったように)。

例、最初の怠惰な量指定子を避けるために、私はこれを使用します:

(?>[^"]++|"(?!id_str":))+

正規表現エンジンは、二重引用符ではないすべての文字を可能な限り取得します (所有量指定子が使用されているため、単一のバックトラック位置を登録せずに)。アンカーid_str":。この部分はすべて、1 回以上繰り返されるアトミック グループ (内部でバックトラックは不可) によってラップされます。

二重引用符が見つかった場合にのみ、すぐに失敗する先読みを内部で使用することを恐れないでください。ただし、 aiよりも頻度が低いことがわかっている場合は"(または、見つかった場合は以前のまれな文字)、 a で同じことを試すことができます。

(?>[^i]++|i(?!d_str":))+id_str":(...

編集:ここでの最良の選択,は、頻度が少ないことのようです: (200ステップ対二重引用符付きの422ステップ)

(\d*+)(?>[^,]++|,(?!"id_str":))+,"id_str":"(\d*+)",(?>[^,]++|,(?!"location":))+,"location":"([^"]*+)"

パフォーマンスを向上させるには、可能であれば、パターンにアンカー ( ^) を追加してみてください。それが文字列または改行 (複数行モードの場合) の始まりである場合。

^(\d*+)(?>[^"]++|"(?!id_str":))+"id_str":"(\d*+)",(?>[^"]++|"(?!location":))+"location":"([^"]*+)"
于 2013-06-22T21:19:28.157 に答える