local s = "http://example.com/image.jpg"
print(string.match(s, "/(.-)%.jpg"))
这给了我
--> /example.com/image
但我想要
--> image
答案 0 :(得分:3)
如果您确定文件名前面的字符串中有/
,则可以:
print(string.match(s, ".*/(.-)%.jpg"))
贪婪的匹配.*/
将根据需要停在最后/
。
答案 1 :(得分:2)
由于正则表达式引擎从左到右处理字符串,因此您的模式发现第一个/
,然后.-
匹配任何字符(.
)尽可能少({{1}最多到第一个文字-
(与.
匹配),后跟%.
子字符串。
你需要使用一个否定的字符类jpg
(以匹配除[^/]
之外的任何字符)而不是匹配任何字符的/
:
.
local s = "http://example.com/image.jpg"
print(string.match(s, "/([^/]+)%.jpg"))
-- => image
匹配任何字符但 [^/]
,因此,最后/
将与模式中的第一个/
匹配{ {1}}。它将匹配为
从模式中移除第一个/
并不是一个好主意,因为它会在尝试查找匹配项时使引擎使用更多冗余步骤,"/([^/]+)%.jpg"
将"锚定" /
符号处的量化子模式。引擎找到/
比查找除/
以外的字符数0+(从头开始未定义)更容易。
如果您确定此字符串出现在字符串的末尾,请在模式的末尾添加/
(如果您需要,则实际上并不清楚,但在一般情况下可能最好)。
答案 2 :(得分:2)
为什么这不匹配非贪婪,只给我一个图像名称?
直接回答问题:.-
不保证最短匹配,因为匹配的左侧部分仍然锚定在当前位置,如果在该位置匹配某些东西,它将作为结果。非贪婪只是意味着只要模式的其余部分匹配,它将消耗与其模式匹配的最少数量的字符。这就是使用[^/]-
修复模式的原因,因为它会找到不是正斜杠的最短字符数以及使用.*/.-
的原因,因为在这种情况下.*
会贪婪地消耗所有内容然后回溯直到满足其余模式(在这种情况下会产生相同的结果)。