簡體   English   中英

正則表達式僅匹配最后一次出現

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM