[英]Regex only matching last occurrence
我的正則表達式是:
genres\\":\\[(?=.*name\\":\\"(.*?)\\"}(?=.*\\"homepage))
我的目標是:
{
"adult":false,
"backdrop_path":"/b9OVFl48ZV2oTLzACSwBpNrCUhJ.jpg",
"belongs_to_collection": {
"id":135468,
"name":"G.I. Joe (Live-Action Series)",
"poster_path":"/5LtZM6zLB2TDbdIaOC5uafjYZY1.jpg",
"backdrop_path":"/m3ip0ci0TnX0ATUxpweqElYCeq4.jpg"
},
"budget":185000000,
"genres":[
{
"id":28,
"name":"Action"
},
{
"id":12,
"name":"Adventure"
},
{
"id":878,
"name":"Science Fiction"
},
{
"id":53,
"name":"Thriller"
}
],
"homepage":"http://www.gijoemovie.com",
"id":72559,
"imdb_id":"tt1583421",
"original_title":"G.I. Joe: Retaliation",
"overview":"Framed for crimes against the country, the G.I. Joe team is terminated by Presidential order. This forces the G.I. Joes into not only fighting their mortal enemy Cobra; they are forced to contend with threats from within the government that jeopardize their very existence.",
"popularity":11.7818680433822,
"poster_path":"/swk1AHwPvIJv8NUFM1qpFuaT642.jpg",
"production_companies":[
{
"name":"Paramount Pictures",
"id":4
},
{
"name":"Metro-Goldwyn-Mayer (MGM)",
"id":8411
}
],
"production_countries":[
{
"iso_3166_1":"US",
"name":"United States of America"
}
],
"release_date":"2013-03-29",
"revenue":371876278,
"runtime":110,
"spoken_languages":[
{
"iso_639_1":"en",
"name":"English"
}
],
"status":"Released",
"tagline":"GI JOE IS NO MORE",
"title":"G.I. Joe: Retaliation",
"vote_average":5.4,
"vote_count":1806
}
我知道它是JSON,我應該使用JSON類或比Regex更好的東西來使用它,但是,在此項目中,我僅限於Regex。
我正在使用http://regexhero.net/tester/測試我的正則表達式,當我應該獲得Action, Adventure, Science Fiction, Thriller
,我只會得到Thriller
。
PS:我正在使用Java和java.util.regex
List<String> generos = new ArrayList<>();
Matcher filter = Pattern.compile("genres\":\\[(?=.*name\":\"(.*?)\"}(?=.*\"homepage))").matcher(response);
while (filter.find()) {
generos.add(filter.group(1));
}
該代碼是完全可以的,唯一的問題是在正則表達式中。 只需在任何Regex Tester中嘗試此正則表達式,您就會發現它只會出現最后一次,但我需要所有這些。
這似乎可行:
(?<!^)(?:genres|\G)[^]]*?"name":"(.*?)"
\\G
本質上與上次匹配結束的位置匹配(如果尚未匹配,則匹配字符串的開頭)。 [ docs ]
因此,由於\\G
可以匹配字符串的開頭(但我們不希望這樣),因此請首先確保我們不在帶有負向后的(?<!^)
的字符串的開頭。
然后,找到“流派”或\\G
(您的匹配項先前保留的位置),然后開始尋找“名稱”。 [^]]*?
的量詞[^]]*?
被懶惰了?
因此它將在找到第一個“名稱”時停止,而不是繼續貪婪地繼續下去,直到它通過其他名稱並僅找到最后一個。
您需要的文本將在第1組中捕獲。
在regexhero中測試:
(?<=genres[^]]{1,200})\"name\":\"[^"]+\"
[^]]
將確保您停留在流派數組中。
首先,嘗試使用正則表達式解析諸如JSON之類的非常規格式是一個糟糕的主意。 我不知道為什么您的老師會要求您嘗試這樣做,除非他/她想讓您知道如何不使用正則表達式的困難方法。
就是說,您不能使用單個正則表達式來做到這一點,至少如果genres
的數量並不總是固定的(至少不太可能是固定的),則無法做到這一點。
您可以分兩個步驟進行操作:
首先,將genres
列表與以下正則表達式匹配:
Pattern regex = Pattern.compile("\"genres\":\\[[^\\[\\]]*\\]");
然后在前一個正則表達式的匹配結果上使用此正則表達式:
Pattern regex = Pattern.compile("\"name\":\"([^\"]*)\"");
(從每個匹配項的.group(1)
中獲取結果)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.