< a123 > < ? 0 ?>\";" />
开发者

Lua string.match problem?

how can I match following strings with one expression?

local a = "[a 1.001523] <1.7 | [...]> < a123 > < ? 0 ?>";

local b = "[b 2.68] <..>";

local c = "[b 2.68] <>";

local d = "[b 2.68] <> < > < ?>";

local name, netTime, argument1, argument2, argumentX = string:match(?);

-- (string is a or b or c or d)

The problem is, the strings can have various counts of arguments( "<...>" ) and the arguments can have numbers, c开发者_开发问答hars, special chars or spaces in it. I'm new to Lua and I have to learn string matching, but I cannot learn this in a few hours. I ask YOU, because I need the result tomorrow and I really would appreciate your help!

cheers :)


Lua patterns are very limited, you can't have alternative expressions and no optional groups. So that means all of your arguments would need to be matched with the same expressions and you would need to use a fixed amount of arguments if you only write a single pattern. Check this tutorial, it doesn't take long to get used to lua patterns.

You might be still able to parse those strings using multiple patterns. ^%[(%a+)%s(%d+%.%d+)%]%s is the best you can do to get the first part, assuming local name can have multiple upper and lower case letters. To match the arguments, run multiple patterns on parts of the input, like <%s*> or <(%w+)> to check each argument individually.

Alternatively get a regex library or a parser, which would be much more useful here.


Lua patterns are indeed limited, but you can get around if you can make some assumptions. Like if there will be no >'s in the arguments you could just loop over all matching pairs of <> :

local a = "[a 1.001523] <1.7 | [...]> < a123 > < ? 0 ?>"
local b = "[b 2.68] <..>"
local c = "[b 2.68] <>"
local d = "[b 2.68] <> < > < ?>"

function parse(str)
    local name,nettime,lastPos = str:match'%[(%a+)%s(%d+%.%d+)%]()'
    local arguments={}
    -- start looking for arguments only after the initial part in [ ] 
    for argument in str:sub(lastPos+1):gmatch('(%b<>)') do
        argument=argument:sub(2,-2) -- strip <>
        -- do whatever you need with the argument. Here we'll just put it in a table
        arguments[#arguments+1]=argument
    end
    return name,nettime,unpack(arguments)
end

For more complicated things you'll be better of using something like LPEG, like kapep said.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜