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