2010-03-11 22 views
3

J'ai écrit un validateur d'URL pour un projet sur lequel je travaille. Pour mes besoins cela fonctionne très bien, sauf quand la dernière partie de l'URL dépasse 22 caractères. Mon expression:Flex 3 Expression régulière Problème

/((https?):\/\/)([^\s.]+.)+([^\s.]+)(:\d+\/\S+)/i 

Il attend une entrée qui ressemble à "http (s): // nom d'hôte: port/emplacement." Quand je lui donne l'entrée:

https://demo10:443/111112222233333444445 

cela fonctionne, mais si je passe l'entrée

https://demo10:443/1111122222333334444455 

il se casse. Vous pouvez le tester facilement au http://ryanswanson.com/regexp/#start. Curieusement, je ne peux pas reproduire le problème avec juste la partie pertinente (je pense) /(:\d+\/\S+)/i. Je peux avoir autant de caractères que nécessaire/et cela fonctionne très bien. Des idées ou des bugs connus?

Edit: Voici un code pour un exemple d'application qui illustre le problème:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> 
<mx:Script> 
    <![CDATA[ 
     private function click():void { 
      var value:String = input.text; 
      var matches:Array = value.match(/((https?):\/\/)([^\s.]+.)+([^\s.]+)(:\d+\/\S+)/i); 
      if(matches == null || matches.length < 1 || matches[0] != value) { 
       area.text = "No Match"; 
      } 
      else { 
       area.text = "Match!!!"; 
      } 
     } 
    ]]> 
</mx:Script> 
<mx:TextInput x="10" y="10" id="input"/> 
<mx:Button x="178" y="10" label="Button" click="click()"/> 
<mx:TextArea x="10" y="40" width="233" height="101" id="area"/> 
</mx:Application> 

Répondre

1

Je débogué votre expression régulière sur RegexBuddy et apparemment, il faut des millions d'étapes pour trouver un match . Cela signifie généralement que quelque chose ne va vraiment pas avec l'expression régulière.

Regardez ([^\s.]+.)+([^\s.]+)(:\d+\/\S+).

1- Il semble que vous essayiez de faire correspondre des sous-domaines aussi, mais cela ne fonctionne pas comme prévu puisque vous n'avez pas échappé au point. Si vous l'échappez, demo10: 443/123 ne correspondra pas car il aura besoin d'au moins un point. Remplacez ([^\s.]+\.)+ par ([^\s.]+\.)* et cela fonctionnera.

2- [^\s.]+ est une classe de caractères incorrecte, elle correspond à toute la chaîne et commence à revenir en arrière à partir de là. Vous pouvez éviter cela en utilisant [^\s:.] qui s'arrêtera au côlon.

Celui-ci devrait fonctionner comme vous voulez: https?:\/\/([^\s:.]+\.)*([^\s:.]+):\d+\/\S+

+0

Fonctionne très bien, merci! Vous avez oublié le slash après le d +, mais pas de soucis. https?: \/\/([^ \ s:.] + \.) * ([^ \ s:.] +): \ d + \/\ S + – Tommy

1

C'est un bug, que ce soit dans la mise en œuvre de Ryan ou dans Flex/Flash.

La syntaxe d'expression régulière utilisée ci-dessus (moins barres obliques et des drapeaux environnants) correspond à Python qui fournit la sortie suivante:

# ignore case insensitive flag as it doesn't matter in this case 
>>> import re 
>>> rx = re.compile('((https?):\/\/)([^\s.]+.)+([^\s.]+)(:\d+\/\S+)') 
>>> print rx.match('https://demo10:443/1111122222333334444455').groups() 
('https://', 'https', 'demo1', '0', ':443/1111122222333334444455') 
+0

Son certainement pas seulement sa mise en œuvre, car il ne fonctionne pas non plus dans mon code. – Tommy

+0

Intéressant. J'ai remarqué que l'implémentation de Ryan commençait à ralentir de plus en plus longtemps, donc je me demande si c'est un problème avec l'algorithme d'analyse de regex. Si vous avez un exemple de code de travail, collez-le. –