Regex: comment faire correspondre n'importe quelle chaîne jusqu'à ce que les espaces, ou jusqu'à ce que la ponctuation suivie par des espaces?

Je suis en train d'écrire une expression régulière qui va trouver les Url dans un texte clair de la chaîne, afin que je puisse les envelopper avec des balises d'ancrage. Je sais qu'il y a les expressions déjà disponibles pour ce, mais je veux créer mon propre, parce que je veux savoir comment il fonctionne.

Depuis, il ne va pas casser quelque chose si ma regex ne parvient pas, mon plan est d'écrire quelque chose de relativement simple. Jusqu'à présent cela signifie que: 1) match "www" ou de "http" au début d'un mot 2) garder correspondance jusqu'à ce que le mot se termine.

Je peux le faire, AFAICT. J'ai ceci: \b(http|www).?[^\s]+

Qui fonctionne sur foo www.example.com bar http://www.example.com etc.

Le problème est que si je lui donne foo www.example.com, http://www.example.com il pense que la virgule est une partie de l'URL.

Donc, si je suis pour utiliser une expression pour ce faire, j'ai besoin de changer "...et arrêtez-vous quand vous voyez des espaces" à "...et arrêtez-vous quand vous voyez des espaces ou un morceau de ponctuation à droite avant d'espaces". C'est ce que je ne suis pas sûr de la façon de faire.

À l'heure actuelle, une solution, je suis à la pensée de courir avec est juste d'ajouter un autre test d'appariement de l'URL, puis sur la ligne suivante le déplacement de tous les sournois signe de ponctuation. Ce n'est pas aussi élégant.

Note: je suis en train d'écrire cela en PHP.

De côté: pourquoi remplacer \s avec \b dans l'expression ci-dessus ne semble pas fonctionner?


ETA:

Merci à tous!

C'est ce que j'ai fini avec, basé sur l'Explosion des Pilules de conseils:

function add_links( $string ) {
    function replace( $arr ) {
        if ( strncmp( "http", $arr[1], 4) == 0 ) {
            return "<a href=$arr[1]>$arr[1]</a>$arr[2]$arr[3]";
        } else {
            return "<a href=" . "http://" . $arr[1] . ">$arr[1]</a>$arr[2]$arr[3]";
        }
    }
return preg_replace_callback( '/\b((?:http|www).+?)((?!\/)[\p{P}]+)?(\s|$)/x', replace, $string );
}

J'ai ajouté un rappel de sorte que tous les liens de commencer par http://, et fait un peu de jongler avec la façon dont il gère la ponctuation.

Ce n'est probablement pas la Meilleure façon de faire les choses, mais il fonctionne. J'ai beaucoup appris à ce sujet dans le dernier peu de temps, mais il y a toujours plus à apprendre!

Salut @Nick, bienvenue. +1 pour un bien formaté question 🙂
Merci et merci à vous!

OriginalL'auteur Nick Loewen | 2013-06-05