有一天我会擅长正则表达式但是现在......
我正在使用以下表达式解析一个查找MP3文件的HTML页面(可以正常工作):
"<A HREF=\"([^\"]+)\"[^>]*>([^<]+?)\\.mp3</A>"
Run Code Online (Sandbox Code Playgroud)
我现在想要搜索MP3和OGG文件.看起来像一个简单的OR修改(.mp3 || .ogg),但我不太确定我是如何把它放在那里的?有关详细信息,请参阅尝试使用Java正则表解析HTML目录列表中的链接.
您有以下Java字符串文字:
// Java string literal
"<A HREF=\"([^\"]+)\"[^>]*>([^<]+?)\\.mp3</A>"
Run Code Online (Sandbox Code Playgroud)
处理完所有转义序列时,此字符串表示的模式为:
// the regex pattern
<A HREF="([^"]+)"[^>]*>([^<]+?)\.mp3</A>
Run Code Online (Sandbox Code Playgroud)
现在让我们分开这个模式:
_________ _ _ E________
<A HREF="([^"]+)"[^>]*>([^<]+?)\.mp3</A>
\_____/ \______/
1 2
Run Code Online (Sandbox Code Playgroud)
所以这个正则表达式的部分是:
<A HREF=" 从字面上看([^"]+),即在第1组中捕获的除了双引号之外的所有内容" 从字面上讲[^>]*,即一切,但 >> 从字面上看([^<]+?),即<第2组中捕获的尽可能少的东西.mp3</A>字面上匹配(.由反斜杠转义)所以看看这个,我们可以观察到正则表达式做出以下假设:
href属性值由第2部分相匹配; 它必须用双引号括起来,并且本身不能包含任何转义的双引号.该匹配被捕获到组1中.href必须是第一个属性,否则正则表达式将不匹配.使用正则表达式解析HTML是一项棘手的工作,但鉴于众多假设,上述正则表达式似乎能够在大多数时间内完成工作.
使用垂直条完成正则表达式的交替.了解其优先级以及分组如何有用非常重要.
this|that 匹配这两个字符串之一:
"this""that"this|that thing 匹配这两个字符串之一:
"this""that thing"(this|that) thing 匹配这两个字符串之一:
"this thing""that thing"(this|that) (thing|stuff) 匹配以下四个字符串之一:
"this thing""that thing""this stuff""that stuff"所以为了允许mp3和ogg扩展,我们可以修改mp3模式中的(mp3|ogg).请注意,此组将匹配并将扩展捕获到组3中.
因此,最终的模式是:
<A HREF="([^"]+)"[^>]*>([^<]+)\.(mp3|ogg)</A>
\_____/ \_____/ \_______/
1:url 2:filename 3:ext
Run Code Online (Sandbox Code Playgroud)
作为Java字符串文字,这是:
"<A HREF=\"([^\"]+)\"[^>]*>([^<]+)\\.(mp3|ogg)</A>"
Run Code Online (Sandbox Code Playgroud)
这[…]是一个角色类.类似于[aeiou]匹配任何一个小写元音的东西.[^…]是一个否定的角色类.[^aeiou]匹配除小写元音之外的任何东西.
这(…)是一个捕获组.它允许稍后检索匹配的字符串.
该*和+是重复符.默认情况下,重复是贪婪(即匹配的多越好).在?在+?使得它不愿(即比赛的几个越好).
注意,它?也可以在其他上下文中用作可选的重复说明符.
这.是一个符合(几乎)任何角色的元字符.因为我们想要一个文字句号,所以我们通过前面的双打来逃避它.
请注意,正则表达式模式默认区分大小写.在Java中,您可能希望使用Pattern.CASE_INSENSITIVEflag((?i)在模式中可嵌入).