RegExpValidator does not validate a URL pattern co

2019-03-06 13:35发布

问题:

The URL http://www.ftd.de/rss2 is not valid when I check it against the below RegEx in this (unadventurous) <mx:RegExValidator> :

<mx:RegExpValidator id="validatorURL" required="true" enabled="true"
    source="{inputURL}" property="text" triggerEvent="focusOut"
    expression="{resourceManager.getString('resources','general.urlRegExp')}"
    flags="i" />

This RegExValidator with the below RegEx validates URLs correctly as long as they don't end with a number. Any other valid URL seems to be valid.

Why is that? Flex bug?


RegEx

I use this RegEx by Diego Perini, which gets the best results in this comparison.

^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$

The RegEx itself works great with the above URL, it validates correctly in any non-flex validator i've tested so far:

  • QuickREx
  • RegExPal
  • JRegExpTester
  • RegExTester

I've checked the RegEx with two Flex-based validators, which both failed to validate any URL at all:

  • http://gskinner.com/RegExr/
  • http://ryanswanson.com/regexp/#start

We use Flex SDK 4.6.0.23201.

回答1:

nhahtdh's answer made me check this issue again. It didn't solve the problem, but it pointed me in the right direction. I'll use the RegExp from his answer, as the suggestion conversion from \uhhhh to \x{hhhh} is necessary as well.

Edit: solution

The actual problem is that when passing a RegExp as String to a RegExpValidator it has to be double escaped. So the Pattern should look like this if it is loaded from a resources file:

general.urlRegExp=^(?:(?:https?|ftp):\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!10(?:\\.\\d{1,3}){3})(?!127(?:\\.\\d{1,3}){3})(?!169\\.254(?:\\.\\d{1,3}){2})(?!192\\.168(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\x{00a1}-\\x{ffff}0-9]+-?)*[a-z\\x{00a1}-\\x{ffff}0-9]+)(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}0-9]+-?)*[a-z\\x{00a1}-\\x{ffff}0-9]+)*(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?$

Now this can be used directly in the RegExpValidator:

<mx:RegExpValidator expression="{resourceManager.getString('resources','general.urlRegExp')}" flags="gmi" />


回答2:

The sequence \uhhhh doesn't seem to be recognized in the 2 online Flex-based testers. This is either a bug in the implementation of Flex regular expression, or possibly a bug in the implementation of the tester, or possibly a mistake in the documentation.

Please check whether the original regex works in your program before using the regex below.

This is a work-around for testing the regex on the online testers: replace all \uhhhh with \x{hhhh}. I am not sure whether it still works in the actual code. This is not documented anywhere, and I just found this out from an answer by other user.

^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$

Demo on RegExr (I used the test data from the link in the question)



回答3:

You can use mx.utils.URLUtil class:

trace(URLUtil.isHttpURL( 'http://www.ftd.de/rss2')); //true

It is also helpful for extracting different parts of url.



标签: regex flex