简体   繁体   English

lua中的正则表达式模式问题

[英]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("/[^/]+/[^/]+/([^/]+)/?[^/]*/?([^/]*)/?[^/]*/?([^/]*)")

Demo 演示

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM