3

I am new to lua scripting language so just trying my hand into this language. I got one task which will parse browser user agent string and will return browser information.

Though i have done lot of R&D on lua to get solid LUA library which does this job but unfortunately i have not found anyone.

So i tried to implement it through by using some PHP UA agent library logic into my lua script. As per PHP library (php us parser) it has its own regex file for all probable user agent string so it actually store all these string in JSON file and match incoming UA string with these regex file data and returned the complete details for incoming user agent.

Now i am also trying to replicate same logic in my lua script, but unfortunately, since lua does not have it own regex library, I am trying to parse UA string with its existing available function. Now I'm stuck here to implement the logic.

here is my UA string

local ua ="Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"

and here is regex code for this string

local pattern =    [[@(Chromium|Chrome)/(\d+)\.(\d+)(?:\.(\d+))?@]]

here is my code get the exact match from UA string

for w in s:gmatch(pattern) do
    ngx.say(w)
end`

after running this code it return me nil or NO values

even i have tried with this pattern also local pattern = [[(Chrome|Chromimum)/%d+]

Now its returning me only only one one match that is "Chrome" where as it should return result like this

[0] => Chrome/39.0.2171
[1] => Chrome
[2] => 39
[3] => 0
[4] => 2171

Where each index represent browser different values like browser name, version,os name etc.

Any help is much appreciated.

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Vish
  • 111
  • 1
  • 13

1 Answers1

1

Lua patterns are not the same as regex. The following regex:

(Chromium|Chrome)/(\d+)\.(\d+)(?:\.(\d+))?

would be rewritten as (note that the | is invalid in lua patterns):

(Chrom[eium]+)/(%d+)%.(%d+)%.?(%d*)

You can see the above at work here.

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
  • 1
    It should be made clear that although your Lua pattern version will work for matching Chromium or Chrome, it's not a quite accurate replacement of the regex as it will also match a lot more unwanted ones (i.e., false positives) than the original regular expression. For example, it will also match Chromeeeemmmm – tonypdmtr Feb 23 '17 at 15:04
  • Thanks Its works for this given sring . But i wonder if i have multiple string which will be matched against the UA string. for example let say if i have (wap[\-\ ]browser|maui|netfront|obigo|teleca|up\.browser|midp|Opera Mini)@i]] Here how can i match netfront or telecol or opera .As all are different strings – Vish Feb 27 '17 at 04:46
  • @VishwanathPandey You can't do so with pure lua patters. Please go through the [`LPeg`](http://www.inf.puc-rio.br/~roberto/lpeg/) library for the same. – hjpotter92 Feb 27 '17 at 04:50
  • @hjpotter92 : I have lrex pcre lib installed in my server . Will it work for me? – Vish Feb 27 '17 at 05:07
  • @VishwanathPandey Sure. You could give it a try. What I meant was that lua patterns by themselves are not sufficient for your case. You'd have to rely on a library for that. – hjpotter92 Feb 27 '17 at 05:14
  • @hjpotter92 : I am using lrex lib and after including its library and calling its funcion like local brow = rex.gmatch(s, m) where s = ua string, m is pattern i am getting following error . attempt to concatenate local 'brow' (a function value) – Vish Feb 27 '17 at 06:19
  • @VishwanathPandey I'd recommend asking a new question specific to the lrex itself. I have no experience with the same. Sorry! – hjpotter92 Feb 27 '17 at 09:03