[英]Regex pattern issue in lua
I have a URL string and need to get certain word from a match. 我有一个URL字符串,需要从匹配中获取某些单词。
Example: 例:
/school/student/studentname1/detail/55/address/address1
I am able to pass to fetch detail of the needed one like, 我能够传递获取所需的细节,如,
local s1,s2,s3 =myString:match("/school/student/(.-)/detail/(.-)/address/(.-)")
Now the problem is that my string can be 现在的问题是我的字符串可以
myString = /school/student/studentname1
or 要么
myString = /school/student/studentname1/detail/55
In that case my regex is failing, any help ? 在那种情况下,我的正则表达式失败,任何帮助?
local all_fields = { student = 1, detail = 2, address = 3 }
local function parse(str)
local info = {}
local index
for w in str:gmatch"/([^/]+)" do
if index then
info[index] = w
index = nil
else
index = all_fields[w]
end
end
return (table.unpack or unpack)(info, 1, 3)
end
local myString = '/school/student/studentname1/detail/55/address/address1'
local s1, s2, s3 = parse(myString)
print(s1, s2, s3)
myString = '/school/student/studentname1/address/address1'
s1, s2, s3 = parse(myString)
print(s1, s2, s3)
myString = '/school/student/studentname1/detail/55'
s1, s2, s3 = parse(myString)
print(s1, s2, s3)
To begin with, your original patter was not working as expected since it did not capture the address (because you used .-
which is not greedy) 首先,你的原始模式没有按预期工作,因为它没有捕获地址(因为你使用.-
这不是贪婪的)
So one way to fix the original patter could be using /school/student/([^/]+)/detail/([^/]+)/address/([^/]+)
因此,修复原始模式的一种方法是使用/school/student/([^/]+)/detail/([^/]+)/address/([^/]+)
where [^/]
means any character except /
其中[^/]
表示除了/
之外的任何字符
Then, in order to optionally match some options and since lua patterns does not allow optional groups, you may need to use several steps like this: 然后,为了可选地匹配某些选项,并且由于lua模式不允许可选组,您可能需要使用以下几个步骤:
myString = "/school/student/studentname1/detail/55"
local s1,s2,s3
s1 =myString:match("/school/student/([^/]+)")
if (s1 ~= nil) then
print(s1)
s2 =myString:match("/detail/([^/]+)")
if (s2 ~= nil) then
print(s2)
s3 =myString:match("/address/([^/]+)")
if (s3 ~= nil) then
print(s3)
end
end
end
Finally, if you want to make sure that detail and address appear exactly on that order, you may use this: 最后,如果您想确保详细信息和地址完全出现在该订单上,您可以使用以下命令:
myString = "/school/student/studentname1/address/myaddress"
local s1,s2,s3
s1 =myString:match("/school/student/([^/]+)")
if (s1 ~= nil) then
print(s1)
s1,s2 =myString:match("/school/student/([^/]+)/detail/([^/]+)")
if (s2 ~= nil) then
print(s2)
s1,s2,s3 =myString:match("/school/student/([^/]+)/detail/([^/]+)/address/([^/]+)")
if (s3 ~= nil) then
print(s3)
end
end
end
That way it will find /school/student/studentname1/detail/55
but it will not find /school/student/studentname1/address/myaddress
. 这样它会找到/school/student/studentname1/detail/55
但它找不到/school/student/studentname1/address/myaddress
。 If you don't need it like this, just use the first version. 如果您不需要这样,只需使用第一个版本。
This is the best one-liner I could come up with: 这是我能提出的最好的单线:
local s1,s2,s3 =myString:match("/[^/]+/[^/]+/([^/]+)/?[^/]*/?([^/]*)/?[^/]*/?([^/]*)")
Explanation: 说明:
I use negated character classes to get the text between slashes in a generic way. 我使用否定字符类以通用方式在斜杠之间获取文本。 This makes it easier to flag the later parts as optional using *
for classes and ?
这样可以更容易地将后面的部分标记为可选,使用*
表示类和?
for slashes (you can make the initial part less generic and just use /school/student/
). 斜杠(你可以使初始部分不那么通用,只需使用/school/student/
)。
This would be easy using (PC)RE, however, Lua Patterns do not support optional capture groups as well as alternations . 这很容易使用(PC)RE,但是,Lua Patterns不支持可选的捕获组以及替换 。 Instead, you can use PCRE patterns in Lua with the rex_pcre library or use the pattern-matching library Lpeg . 相反,您可以将Lua中的PCRE模式与rex_pcre库一起使用,或使用模式匹配库Lpeg 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.