之后如何使用Regex从具有可选字符串的字符串中提取字符?

时间:2018-07-08 22:14:33

标签: regex

我正在学习正则表达式,并且一直处于这种情况下。我的网址可以处于两种状态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中搜索了一些“可能已经有您的答案的问题”建议,但没有找到这种情况,所以我希望问问还可以!

3 个答案:

答案 0 :(得分:2)

这应该有效:

 track\/(\w+)

请参阅here

由于track是这两个字符串的一部分,并且ID由字母数字字符组成,因此上述与字符串“ track /”匹配并捕获该字符串后的字母数字字符的正则表达式应提供所需的ID。

答案 1 :(得分:2)

由于量词(.的贪婪,正则表达式中的捕获组正在尝试尽可能匹配任何内容(*)。

使用时:

  • (?<=track\/)(.*)(?=\?)

仅捕获第一个示例中的1HYcYZCOpaLjg51qUg8ilA,因为第二个示例中没有问号。

使用时:

  • (?<=track\/)(.*)(?=\??)

您实际上是在使正向前瞻性成为可选选项,因此捕获组将尝试尽可能地匹配(包括问号),以便匹配1HYcYZCOpaLjg51qUg8ilA?si=Nf5w1q9MTKu3zG_CJ83RWA1HYcYZCOpaLjg51qUg8ilA,而不会匹配所需的输出。

只匹配字母数字字符\w可能比匹配任何内容都合适。

  • (?<=track\/)(\w*)(?=\??)

或者,如果您需要其他字符,比如说连字符-或下划线_,则可以使用字符类。

  • (?<=track\/)([a-zA-Z0-9_-]*)(?=\??)

或者您可能想捕获所有带有否定字符类的问号?除。

  • (?<=track\/)([^?]*)(?=\??)

正如gaganso指出的那样,在这种情况下(或实际上是先行),不必进行先行搜索,但是,开始与它们一起玩确实是个好主意。环顾断言实际上并不占用字符串中的字符。如您所见here,这两个匹配项的完全匹配项仅由捕获组捕获的内容组成。您可能会找到更多信息here

答案 2 :(得分:0)

正则表达式:(\w+(?=\?))|(\w+&) 请参见正则表达式演示https://regexr.com/3s4gv。 这将首先尝试搜索带有“?”的单词紧接其后,如果未成功,它将获取最后一个单词。