为什么这不匹配非贪婪,只给我一个图像名称?

时间:2017-06-22 21:52:10

标签: string lua lua-patterns

local s = "http://example.com/image.jpg"
print(string.match(s, "/(.-)%.jpg"))

这给了我

--> /example.com/image

但我想要

--> image

3 个答案:

答案 0 :(得分:3)

如果您确定文件名前面的字符串中有/,则可以:

print(string.match(s, ".*/(.-)%.jpg"))

贪婪的匹配.*/将根据需要停在最后/

答案 1 :(得分:2)

由于正则表达式引擎从左到右处理字符串,因此您的模式发现第一个/,然后.-匹配任何字符(.)尽可能少({{1}最多到第一个文字-(与.匹配),后跟%.子字符串。

enter image description here

你需要使用一个否定的字符类jpg(以匹配除[^/]之外的任何字符)而不是匹配任何字符的/

.

请参阅online Lua demo

local s = "http://example.com/image.jpg" print(string.match(s, "/([^/]+)%.jpg")) -- => image 匹配任何字符 [^/],因此,最后/将与模式中的第一个/匹配{ {1}}。它将匹配为

enter image description here

从模式中移除第一个/并不是一个好主意,因为它会在尝试查找匹配项时使引擎使用更多冗余步骤,"/([^/]+)%.jpg"将"锚定" /符号处的量化子模式。引擎找到/比查找除/以外的字符数0+(从头开始未定义)更容易。

如果您确定此字符串出现在字符串的末尾,请在模式的末尾添加/(如果您需要,则实际上并不清楚,但在一般情况下可能最好)。

答案 2 :(得分:2)

  

为什么这不匹配非贪婪,只给我一个图像名称?

直接回答问题:.-不保证最短匹配,因为匹配的左侧部分仍然锚定在当前位置,如果在该位置匹配某些东西,它将作为结果。非贪婪只是意味着只要模式的其余部分匹配,它将消耗与其模式匹配的最少数量的字符。这就是使用[^/]-修复模式的原因,因为它会找到不是正斜杠的最短字符数以及使用.*/.-的原因,因为在这种情况下.*会贪婪地消耗所有内容然后回溯直到满足其余模式(在这种情况下会产生相同的结果)。

相关问题