At 20:53 02/09/2005, you wrote:
I need to create a pattern that match will match a comma delimited string, with no spaces around the commas. Trailing commas aren't allowed either.
This will be used in a form data validation method.


For example, I'd be looking at strings like the following:

1,2,3,4         is a match
1, 2, 3 , 4     isn't a match
1,2,3,4,        isn't (trailing comma)

The tricky part is that I don't know in advance how many items will be in the string, so I need to match repeating sub-patterns.

$pattern := "/" + "^([0-9a-zA-Z]+)((,[0-9a-zA-Z]+)+)" + "/"
array text ($outMatches;0)
$isMatch:= regex match($pattern;$subject;$outMatches)
if ($isMatch)
        dump array ($outMatches)
end if

A few points:

- I'm not sure why you separated the "/" from the pattern, maybe for visual clarity, but of course it isn't necessary.

Yes, for visual clarity. This was for my benefit.

In using various tools that have regexp support, I've found that some regexp patterns require the begin/end slashes, while others don't. For example, I don't think the QFree regexp commands do (even though they are PCRE). When switching tools I always have to refer to their particular regexp pattern syntax.

- This pattern will fail if there is only one item, it requires at least two items.

- This pattern will succeed even if there is any arbitrary junk after the last item it matches, for example "1,2,3 foobar". You need to add '$' at the end of the pattern.

I'd refined my pattern to include that after sending this post.

- You don't actually need to capture the first item in a subpattern.

- This pattern matches items 2-N twice for each item, it is unnecessary to nest the subpatterns, "^([0-9a-zA-Z]+)(,[0-9a-zA-Z]+)+$" is preferable.

- Don't try to use the regex pattern to split the items, once you know it the string matches the pattern, use the 'split string' command. So it's better to just omit the $outMatches argument altogether.

- [0-9a-zA-Z] can be more concisely expressed as \w if you allow underscores as well, or [[:alnum:]] if not.

In this case the list items are acronyms that conform to the above pattern. Thanks for reminding me about the [[:alnum]] alternative. I always forget about those.


- In the latest beta, there are two new operators that do regex matching. =~ does a regex match and returns the same result. #~ does a regex match and returns the inverse of the result (true if it does not match). So you could do this:

if ($subject =~ $pattern)
  // whatever
end if

Very cool! This will be used in a system that still runs 3.0 though.

- If you are just using a library command once or twice, there is no need to import the library, just use the full library.method syntax and the library is auto-imported. So in the example above it would have been easier to use a4d.web.dump array($outMatches).


Here's my version that addresses all of the above points:

$subject := "foo_bar,2,foo,3,bar"
$pattern := "/^\w+(,\w+)*$/"

if ($subject =~ $pattern)
   split string($subject; ","; $items)
   a4d.web.dump array($items)
end if

Hope this helps.

Definitely. Thanks!

-- Brad

_______________________________________________
Active4D-dev mailing list
[email protected]
http://mailman.aparajitaworld.com/mailman/listinfo/active4d-dev
Archives: http://mailman.aparajitaworld.com/archive/active4d-dev/

Reply via email to