如何用正则表达式筛选年份大于1999的Title参数值
解决JSON中筛选年份>1999的Title问题
问题根源
你用的正则"Title":"([^"]+?)".*?"Year":20[0-9]{2}之所以会匹配所有Title,是因为.*?会匹配任意字符(包括换行、其他JSON对象的内容),导致前面对象的Title会和后面对象的Year产生错误关联——比如第一个Title会匹配到最后一个对象的2018年份,从而被错误捕获。
推荐方案:用JSON解析工具处理(不推荐正则)
正则不是处理JSON的合适工具,JSON是结构化数据,用专门的解析器能更准确、高效地完成筛选。以下是两种常见语言的实现示例:
Python示例
import json # 加载JSON数据 json_data = ''' { "Data": { "Items": [ { "Start": "2018-04-05T05:00:00Z", "End": "2018-04-05T05:30:00Z", "Title": "Indiana Jones and the Raiders of the Lost Ark", "Staff": { "Director": "Steven Spielberg", "Starring": "Harrison Ford" }, "TimeZone": "UTC", "Id": "6ec29f07-c845-4967-9c87-716825265312", "Year": 1981, "IsNew": false, "ReadOnly": true }, { "Start": "2018-06-29T12:00:00Z", "End": "2018-06-29T12:30:00Z", "Title": "The Lion King", "Staff": { "Director": "Roger Allers", "Starring": "James Earl Jones" }, "TimeZone": "UTC", "Id": "9d54f04d-3554-4b61-8077-0cfb79cb86db", "Year": 1994, "IsNew": false, "ReadOnly": true }, { "Start": "2018-06-01T08:00:00Z", "End": "2018-06-01T08:30:00Z", "Title": "Titanic ", "Staff": { "Director": "James Cameron", "Starring": "Leonardo DiCaprio" }, "TimeZone": "UTC", "Id": "aa174cd4-da58-4bf9-a7a7-7ae562b584e6", "Year": 1997, "IsNew": false, "ReadOnly": true }, { "Start": "2018-04-27T07:00:00Z", "End": "2018-04-27T07:30:00Z", "Title": "Ready Player One", "Staff": { "Director": "Steven Spielberg", "Starring": "Tye Sheridan" }, "TimeZone": "UTC", "Id": "425b2969-8ec0-4943-93ce-c5a1aec148b0", "Year": 2018, "IsNew": true, "ReadOnly": false } ], "From": 0, "Portion": 0, "TotalCount": 0 }, "RedirectViewModel": null, "ExceptionViewModel": null } ''' data = json.loads(json_data) # 筛选Year>1999的Title filtered_titles = [item["Title"] for item in data["Data"]["Items"] if item["Year"] > 1999] print(filtered_titles)
运行后会输出:['Ready Player One']
JavaScript示例
const jsonData = `{ "Data": { "Items": [ { "Start": "2018-04-05T05:00:00Z", "End": "2018-04-05T05:30:00Z", "Title": "Indiana Jones and the Raiders of the Lost Ark", "Staff": { "Director": "Steven Spielberg", "Starring": "Harrison Ford" }, "TimeZone": "UTC", "Id": "6ec29f07-c845-4967-9c87-716825265312", "Year": 1981, "IsNew": false, "ReadOnly": true }, { "Start": "2018-06-29T12:00:00Z", "End": "2018-06-29T12:30:00Z", "Title": "The Lion King", "Staff": { "Director": "Roger Allers", "Starring": "James Earl Jones" }, "TimeZone": "UTC", "Id": "9d54f04d-3554-4b61-8077-0cfb79cb86db", "Year": 1994, "IsNew": false, "ReadOnly": true }, { "Start": "2018-06-01T08:00:00Z", "End": "2018-06-01T08:30:00Z", "Title": "Titanic ", "Staff": { "Director": "James Cameron", "Starring": "Leonardo DiCaprio" }, "TimeZone": "UTC", "Id": "aa174cd4-da58-4bf9-a7a7-7ae562b584e6", "Year": 1997, "IsNew": false, "ReadOnly": true }, { "Start": "2018-04-27T07:00:00Z", "End": "2018-04-27T07:30:00Z", "Title": "Ready Player One", "Staff": { "Director": "Steven Spielberg", "Starring": "Tye Sheridan" }, "TimeZone": "UTC", "Id": "425b2969-8ec0-4943-93ce-c5a1aec148b0", "Year": 2018, "IsNew": true, "ReadOnly": false } ], "From": 0, "Portion": 0, "TotalCount": 0 }, "RedirectViewModel": null, "ExceptionViewModel": null }`; const data = JSON.parse(jsonData); const filteredTitles = data.Data.Items.filter(item => item.Year > 1999).map(item => item.Title); console.log(filteredTitles);
运行后会输出:['Ready Player One']
迫不得已用正则的修正方案
如果必须用正则,需要限制Title和Year在同一个JSON对象内,避免跨对象匹配。修正后的正则如下:
"Title":"([^"]+?)"(?:(?!{)[\s\S])*?"Year":20\d{2}
正则说明
(?:(?!{)[\s\S])*?:非捕获组,匹配任意字符([\s\S]匹配所有字符包括换行),但遇到{就停止,确保只在当前JSON对象内匹配内容,避免关联到下一个对象的Year值。
注意:这种正则仅适用于结构简单的JSON,若JSON嵌套更复杂(比如对象内还有嵌套对象包含{),依然会出错,所以优先推荐用JSON解析工具。
内容的提问来源于stack exchange,提问作者Md. Ismiel Hossen Abir
相关产品推荐
相关产品推荐

