为什么这个用于解析m3u的正则表达式不起作用?

时间:2018-03-18 17:37:51

标签: regex

m3u文件如下所示:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:153741
#EXT-X-ALLOW-CACHE:NO
#EXT-X-TARGETDURATION:11
#EXTINF: 10.005333 中,
/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-29.ts
#EXTINF: 9.984000 中,
/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-39.ts
#EXTINF: 10.005333 中,
/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-49.ts
#EXTINF: 10.005333 中,
/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-59.ts
#EXTINF: 10.005333 中,
/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-59-09.ts
#EXTINF: 9.984000 中,
/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-59-19.ts

我想用粗体提取对。例如: -
10.005333
/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-29.ts

我设法只部分地解决了这个问题。以下正则表达式给出了持续时间(#EXT-INF:之后的数字)

(?<=^EXTINF:)?(\d+\.\d+)(?=,\r|,\n)

但是,当我尝试在最后添加一些正则表达式时,像^(.*)这样的东西来捕获从\ r或\ n开始之后的任何内容,我什么也得不到。我需要在#EXTINF后面的数字后紧跟在后面的行中捕获任何内容:有人可以帮忙吗?

更新

  

const char * const pm3u =
{
“#EXTM3U \ n”“#EXT-X-VERSION:3 \ n”
  “#EXT-X-MEDIA-SEQUENCE:153741 \ n”
“#EXT-X-ALLOW-CACHE:NO \ n”
  “#EXT-X-TARGETDURATION:11 \ n”
“#EXTINF:10.005333,\ n”

  “/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-29.ts\n”
  “#EXTINF:9.984000,\ n”
  “/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-39.ts\n”
  “#EXTINF:10.005333,\ n”
  “/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-49.ts\n”
  “#EXTINF:10.005333,\ n”
  “/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-59.ts\n”
  “#EXTINF:10.005333,\ n”
  “/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-59-09.ts\n”
  “#EXTINF:9.984000,\ n”
  “/ RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-59-19.ts\n”
};

     

int main()
{
      std :: regex regExpression(“(#EXTINF:)(\\ d +。\\ d +)*”);
      std :: smatch regExMatch;
      const std :: string str(pm3u);

      bool b = std :: regex_match(str.begin(),str.end(),regExMatch,regExpression);

  返回0;
  }

2 个答案:

答案 0 :(得分:0)

此正则表达式将为您提供捕获组1&amp;中的 2

EXTINF:(\d+\.\d+),\r?\n(.*)

https://regex101.com/r/ZYGhZy/1

答案 1 :(得分:0)

如果

,您的正则表达式可以修复
  • 您将lookbehind转换为消费模式
  • 如果您将^替换为(?:^|\n)以匹配行的开头,而不仅仅是字符串的开头
  • 如果您使用std::sregex_iterator来匹配多个匹配而不是std::regex_match只匹配整个字符串(即模式必须与整个字符串匹配)
  • 如果您在#之前添加EXTINF,因为您的预期匹配始于#EXTINF

使用

const std::regex rx(R"((?:^|\n)#EXTINF:(\d+\.\d+),[\r\n]+(.*))");
   std::string test = "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-MEDIA-SEQUENCE:153741\n#EXT-X-ALLOW-CACHE:NO\n#EXT-X-TARGETDURATION:11\n#EXTINF:10.005333,\n/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-29.ts\n#EXTINF:9.984000,\n/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-39.ts\n#EXTINF:10.005333,\n/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-49.ts\n#EXTINF:10.005333,\n/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-58-59.ts\n#EXTINF:10.005333,\n/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-59-09.ts\n#EXTINF:9.984000,\n/RTS_1_009/audio/2018-03-16-H13/audio-2018-03-16-13-59-19.ts";
   for(std::sregex_iterator i = std::sregex_iterator(test.begin(), test.end(), rx);
                         i != std::sregex_iterator();
                         ++i)
   {
    std::smatch m = *i;
    std::cout << "Part 1:"  << m[1].str() << "\nPart 2:"  << m[2].str() << std::endl;
   }

正则表达式是

(?:^|\n)#EXTINF:(\d+\.\d+),[\r\n]+(.*)

请参阅this regex demo online