regex - REGEX - 如何递归地捕获一个组?
问题描述
{"dir":"false", "bytes":158481, "parent_folder":"/Annie/FROM OLD DVDS", "name":"1.jpg"}, {"dir":"false", "bytes ":382661, "parent_folder":"/Annie/FROM OLD DVDS", "name":"2.jpg"}, {"dir":"false", "bytes":1455205, "parent_folder":"/Annie /FROM OLD DVDS", "name":"3.jpg"}
这是我当前的 REGEX 字符串,它只捕获第一个匹配项:
(false.+\"name\"\:\")(.+\.(jpg|jpeg|png))(\")
我想捕捉每一个名字,而不仅仅是第一个。目前它只解析 3.jpg 最后一个。
想要的结果:
1.jpg、2.jpg、3.jpg
解决方案
name
首先...除非您知道该属性将出现的确切次数,否则您将无法使用正则表达式捕获所有名称。例如,如果您知道字符串将包含 3 个name
属性,那么您可以编写一个看起来像.*"name":"(.*?)".*"name":"(.*?)".*"name":"(.*?)".*
这样的正则表达式,它将捕获 3 组名称。
您的正则表达式没有捕获名字,它实际上捕获了姓氏。这是因为您使用了一个贪婪的量词和一个通配符.*
。您必须考虑到{
和}
标记表示一个新对象。所以你需要使用它 [^{}]*?
来确保你一次只看一个对象。量词是一个惰性匹配,*?
所以它只会匹配需要的字符,不像+
or*
会匹配尽可能多的字符。
您还可以利用非捕获组(?:)
来匹配扩展而不捕获它们。这里的想法是确保我们捕获的唯一内容是名称的值。与您当前的正则表达式不同,它捕获多个组。最终的正则表达式如下所示:
.*?{"dir":"false"[^{}]*?"name":"([^{}]*?(?:jpg|jpeg|png))"}.*?
在 C# 中,导入System.Text.RegularExpressions
所有正则表达式需求。您可以使用 查找正则表达式的所有匹配项Regex.Matches
。循环遍历结果MatchCollection
并从匹配中提取所有匹配和捕获。在您的情况下,您的代码可能看起来像
string text = @"{""dir"":""false"", ""bytes"":158481, ""parent_folder"":""/Annie/FROM OLD DVDS"", ""name"":""1.jpg""}, {""dir"":""false"", ""bytes"":382661, ""parent_folder"":""/Annie/FROM OLD DVDS"", ""name"":""2.jpg""}, {""dir"":""false"", ""bytes"":1455205, ""parent_folder"":""/Annie/FROM OLD DVDS"", ""name"":""3.jpg""}";
string search = ".*?{\"dir\":\"false\"[^{}]*?\"name\":\"([^{}]*?(?:jpg|jpeg|png))\"}.*?";
MatchCollection matches = Regex.Matches(text, search);
foreach(Match match in matches){
GroupCollection groups = match.Groups;
Console.WriteLine(groups[1].Value);
}
根据您的用例(正如@adam 建议的那样),隔离每个对象并使用 Json Deserializer 将字符串转换为对象列表可能会有所帮助。与依赖您自己的正则表达式相比,使用起来更容易,更易于维护和健壮得多。
推荐阅读
- javascript - 结合jquery和剑道的例子
- javascript - 使用“onclick”事件模拟元素的中间点击
- excel - Excel VBA在数字字符串中添加零
- algorithm - 在其并集是整个图的图中找到大小相等的互斥完整子图
- r - R Shiny App HighCharter OHLC/Candlesticks 默认缩放周期
- java - string.replace() 中预期的变量
- matlab - 在 Matlab 和 Julia 中读取二进制文件时的不同输出
- angular - 如何测试在其他函数中调用的异步函数?
- c++ - .exe 不能在路径中使用多个“../”实例运行
- r - 使用 tidyverse 将数据拆分为列表并在每个列表中进行操作