2012-11-15 6 views
0

J'ai écrit une expression régulière plutôt lourde à utiliser dans un projet coffee-script. Il est prévu de prendre un gros morceau de texte utilisateur (messages, messages, prose) et de trouver toutes les URL potentielles là-bas, étant aussi gourmand que possible.URL Guesser Optimisation RegExp

urlGrabber = /// 
    (\s|^)        # Start after a whitespace or string[0] 
    ([a-zA-Z]+\://)?     # Captures any protocol (just not //) 
    (\w+:\[email protected])?       # Username:Password 
    ([a-zA-Z\d-]|[a-zA-Z\d-]\.)*  # Subdomains 
    [a-zA-Z\d-]{2,}      # Domain name 
    \.         # THE DOT 
    ([a-zA-Z]{2,4}(:\d+)?)    # Domain Extension with Port 
    ([/\?\#][\S/]*)*     # Some Request, greedy capture 
    \b         # Last word boundary 
    /?         # Optional trailing Slash 
///g 

Je suis en cours d'exécution avec des problèmes comme chaîne abc.mno.st.u.xvyabs.mno.st obtient analysables comme une chaîne. Cela ne devrait pas être capturé du tout. Idem pour as.ds.d.as.ds est capturé.

Quelqu'un peut-il expliquer pourquoi cela se produit et/ou aider avec les changements nécessaires pour résoudre ce problème?

+1

On ne sait pas très bien ce que vous ne voulez pas faire correspondre. Ajouter un espace '\ s' à la fin résoudrait-il votre problème? – Tim

+1

ça aide, mais il semble que je mange mon espace blanc. Comment est-ce que je peux correspondre mais ne pas consommer ceux qui suivent \ s? – arvidkahl

Répondre

1

Utiliser modèle regex

(?:\s+|^)             # leading spaces 
([a-zA-Z]+://|)            # protocol 
(\w+:\[email protected]|)             # username:[email protected] 
((?:[a-zA-Z\d]+(?:-[a-zA-Z\d]+)*\.)*)      # subdomain(s) 
([a-zA-Z\d]+(?:[a-zA-Z\d]|-(?=[a-zA-Z\d]))*[a-zA-Z\d])  # domain 
(\.[a-zA-Z]{2,4})           # .top-level-domain 
(:\d+|)              # :port 
(/\S*|)              # rest of url 
(?!\S) 

Note: et le domaine des sous-domaines ne peuvent pas commencer et se termine par - et il devrait y avoir pas de double -- aussi bien (sauf si vous voulez soutenir Punnycode pour IDN domain names).

+0

Merci beaucoup, c'est beaucoup plus clair. – arvidkahl

+0

Les parties '(? <= [A-zA-Z \ d])' semblent perturber mon analyseur d'expression rationnelle. Pouvez-vous nous expliquer un peu s'il vous plaît? – arvidkahl

+1

@arvidkahl - C'est un lookbehind positif. Certains compilateurs ne supportent pas cette fonctionnalité regex. J'ai mis à jour ma réponse avec une solution qui n'utilise pas lookbehind. –