0

I'm supposed to enforce a certain search-syntax in a text input, and after watching several RegEx videos and tutorials, I'm still having difficulties creating a regex for my purpose. The expression structure should be something like that: $earch://site.com?y=7, app=app1, wu>7, cnt<>8, url=http://kuku.com?adasd=343 , p=8

may start with a free text search that may contain any character other than the delimiter, which is ,. (free text must be first, and the string may be ONLY free text search).

after free text comma-separated parts of field names which consist only [a-z][A-Z], followed by operator: (=|<|>|<>) and followed by field search value that may be anything but ,.

between the commas that separate the parts there may be spaces (\s*).

The free text part or at least one field=value must appear in order for the string to be valid.

Did anyone understand the question? :)

nadavelyashiv
  • 309
  • 1
  • 3
  • 12
  • 1
    I'm not sure if I understood everything, but how's `^[^,]*(?:,\s*[a-zA-Z]+(?:[=><]|<>)[^,]+)*$`? – Aran-Fey May 18 '16 at 14:52
  • 1
    Thanks, that seems to work. Why did you use non-capturing groups? Plus - if I start out the string with a comma, it is valid, whereas I want it to not be valid (if there's no free text at the beginning). – nadavelyashiv May 19 '16 at 11:36

1 Answers1

0

^[^,]*(?:,\s*[a-zA-Z]+(?:[=><]|<>)[^,]+)*$? – Rawing

Thanks, that seems to work. Why did you use non-capturing groups?

He did it most probably because he didn't assume that the groups are to be captured (you didn't specify that).

Plus - if I start out the string with a comma, it is valid, whereas I want it to not be valid (if there's no free text at the beginning).

That can be accomplished by changing the first * to a +, i. e. ^[^,]+…

I'm using javascript. I want to be able to separate each key=value pair (including the possible free text as a group), and within that group I would like to be able to capture key, operator, and value as separate entities (or groups)

That's not doable with only one RegExp invocation, see e. g. How to capture an arbitrary number of groups in JavaScript Regexp? Here's an example solution:

s = '$earch://site.com?y=7,   app=app1,  wu>7, cnt<>8,    url=http://kuku.com?adasd=343  ,   p=8'
part = /,\s*([a-zA-Z]+)(<>|[=><])([^,]+)/
re = RegExp('^([^,]+)('+part.source+')*$')
freetext = re.exec(s)[1]  // validate s and take free text as 1st capture group of re
if (freetext)
{   document.write('free text:', freetext, '<p>')
    parts = RegExp(part.source, 'g')
    m = s.slice(freetext.length).match(parts) // now get all key=value pairs into m[]
    if (m)
    {   field = []
        for (i = 0; i < m.length; ++i)
        {   f = m[i].match(part) // and now capture key, operator and value from m[i]
            field[i] = { key:f[1], operator:f[2], value:f[3] }
            for (property in field[i]) // display them
                document.write(property, ':', field[i][property], '; ')
            document.write('<p>')
        }
        document.write(field.length, ' key/value pairs total<p>')
    }
}
Community
  • 1
  • 1
Armali
  • 18,255
  • 14
  • 57
  • 171
  • Thanks for the comment. How can I make the expression capture the groups? – nadavelyashiv Jun 26 '16 at 12:57
  • @nadavelyashiv: The group is capturing if we omit the `?:`, but … group**s**? There is only one group. How to retrieve multiple instances of it depends on the programming language used; you'd need to state it. – Armali Jun 27 '16 at 08:00
  • 1
    I'm using javascript. I want to be able to separate each key=value pair (including the possible free text as a group), and within that group I would like to be able to capture key, operator, and value as separate entities (or groups) – nadavelyashiv Jun 28 '16 at 13:36
  • 1
    @nadavelyashiv: I expanded the answer accordingly. – Armali Jun 30 '16 at 07:52