我正在学习正则表达式,并且一直处于这种情况下。我的网址可以处于两种状态EXAMPLE 1
:
spotify.com/track/1HYcYZCOpaLjg51qUg8ilA?si=Nf5w1q9MTKu3zG_CJ83RWA
或EXAMPLE 2
:
spotify.com/track/1HYcYZCOpaLjg51qUg8ilA
我需要提取1HYcYZCOpaLjg51qUg8ilA
ID
到目前为止,我使用的是:(?<=track\/)(.*)(?=\?)?
在示例2中效果很好,但在与示例1匹配时包含?si=Nf5w1q9MTKu3zG_CJ83RWA
。
但是,如果我删除表达式末尾的?
,则它适用于示例1,但不适用于示例2!这不是说最后一组(?=\?)
是可选的,应该匹配吗?
我要去哪里错了?
谢谢!
我从SO中搜索了一些“可能已经有您的答案的问题”建议,但没有找到这种情况,所以我希望问问还可以!
答案 0 :(得分:2)
这应该有效:
track\/(\w+)
请参阅here。
由于track是这两个字符串的一部分,并且ID由字母数字字符组成,因此上述与字符串“ track /”匹配并捕获该字符串后的字母数字字符的正则表达式应提供所需的ID。
答案 1 :(得分:2)
由于量词(.
的贪婪,正则表达式中的捕获组正在尝试尽可能匹配任何内容(*
)。
使用时:
(?<=track\/)(.*)(?=\?)
仅捕获第一个示例中的1HYcYZCOpaLjg51qUg8ilA
,因为第二个示例中没有问号。
使用时:
(?<=track\/)(.*)(?=\??)
您实际上是在使正向前瞻性成为可选选项,因此捕获组将尝试尽可能地匹配(包括问号),以便匹配1HYcYZCOpaLjg51qUg8ilA?si=Nf5w1q9MTKu3zG_CJ83RWA
和1HYcYZCOpaLjg51qUg8ilA
,而不会匹配所需的输出。
只匹配字母数字字符\w
可能比匹配任何内容都合适。
(?<=track\/)(\w*)(?=\??)
或者,如果您需要其他字符,比如说连字符-
或下划线_
,则可以使用字符类。
(?<=track\/)([a-zA-Z0-9_-]*)(?=\??)
或者您可能想捕获所有带有否定字符类的问号?
除。
(?<=track\/)([^?]*)(?=\??)
正如gaganso指出的那样,在这种情况下(或实际上是先行),不必进行先行搜索,但是,开始与它们一起玩确实是个好主意。环顾断言实际上并不占用字符串中的字符。如您所见here,这两个匹配项的完全匹配项仅由捕获组捕获的内容组成。您可能会找到更多信息here。
答案 2 :(得分:0)
正则表达式:(\w+(?=\?))|(\w+&)
请参见正则表达式演示https://regexr.com/3s4gv。
这将首先尝试搜索带有“?”的单词紧接其后,如果未成功,它将获取最后一个单词。