web-dev-qa-db-fra.com

JavaScript Regex pour correspondre à une URL dans un champ de texte

Comment configurer mon regex pour vérifier si une URL est contenue dans un bloc de texte en javascript. Je n'arrive pas à comprendre le modèle à utiliser pour accomplir cela

 var urlpattern = new RegExp( "(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?"

 var txtfield = $('#msg').val() /*this is a textarea*/

 if ( urlpattern.test(txtfield) ){
        //do something about it
 }

MODIFIER:

Donc, le modèle que j'ai maintenant fonctionne dans les testeurs de regex pour ce que j'ai besoin de faire, mais chrome jette une erreur

  "Invalid regular expression: /(http|ftp|https)://[w-_]+(.[w-_]+)+([w-.,@?^=%&:/~+#]*[w-@?^=%&/~+#])?/: Range out of order in character class"

pour le code suivant:

var urlexp = new RegExp( '(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?' );
22
BillPull

Même si échapper aux tirets (qui peut avoir une signification spéciale en tant que spécificateurs de plage de caractères lorsque vous êtes dans une classe de caractères) devrait fonctionner, une autre méthode pour supprimer leur signification particulière consiste à les mettre au début ou à la fin de la classe définition. 

De plus, \+ et \@ dans une classe de caractères sont en effet interprétés respectivement par + et @ par le moteur JavaScript; toutefois, les échappées ne sont pas nécessaires et peuvent dérouter quelqu'un qui tente d'interpréter visuellement la regex.

Je recommanderais la regex suivante pour vos besoins:

(http|ftp|https)://[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?

cela peut être spécifié en JavaScript soit en le passant dans le constructeur RegExp (comme vous l'avez fait dans votre exemple):

var urlPattern = new RegExp("(http|ftp|https)://[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?")

ou en spécifiant directement un littéral de regex, en utilisant la méthode de cotation //:

var urlPattern = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/

Le constructeur RegExp est nécessaire si vous acceptez une expression rationnelle sous forme de chaîne (entrée utilisateur ou appel AJAX, par exemple), et peut être plus lisible (comme c'est le cas dans ce cas). Je suis à peu près certain que la méthode de cotation // est plus efficace et, à certains moments, plus lisible. Les deux fonctionnent.

J'ai testé votre version originale et cette modification à l'aide de Chrome à la fois sur < JSFiddle > et sur < RegexLib.com >, à l'aide du moteur de regex côté client (navigateur) et en sélectionnant spécifiquement JavaScript. Alors que le premier échoue avec l'erreur que vous avez déclarée, la modification suggérée réussit. Si je supprime la h de la http dans le source, elle ne correspond pas, comme il se doit!

Modifier

Comme l'a noté @noa dans les commentaires, l'expression ci-dessus ne correspondra pas aux serveurs de réseau local (non Internet) ni à aucun autre serveur auquel on accède avec un seul mot (par exemple, http://localhost/... ou https://sharepoint-test-server/...). Si vous souhaitez que ce type d'URL corresponde (ce qu'il peut être ou non), les éléments suivants pourraient être plus appropriés:

(http|ftp|https)://[\w-]+(\.[\w-]+)*([\w.,@?^=%&amp;:/~+#-]*[\w@?^=%&amp;/~+#-])?

#------changed----here-------------^

<Fin éditer>

Enfin, une excellente ressource qui m’a appris 90% de ce que je sais sur regex est Regular-Expressions.info - Je le recommande vivement si vous souhaitez apprendre le regex (ce qu’il peut faire et ce qu’il ne peut pas faire) !

64
Code Jockey

Vous devez échapper à la barre oblique inverse lorsque vous utilisez new RegExp

Vous pouvez également mettre le tiret - à la fin de la classe de caractères pour éviter de l’échapper.

&amp; à l'intérieur d'une classe de caractères signifie & or a or m or p or ;, il vous suffit de mettre & et ;, a, m and p sont déjà appariés par \w.

Alors, votre regex devient:

var urlexp = new RegExp( '(http|ftp|https)://[\\w-]+(\\.[\\w-]+)+([\\w-.,@?^=%&:/~+#-]*[\\w@?^=%&;/~+#-])?' );
4
Toto

Voici le modèle d'analyse d'URL unique le plus complet.

Cela fonctionne avec N'IMPORTE QUEL URI/URL dans N'IMPORTE QUELLE sous-chaîne!

https://regex101.com/r/jO8bC4/5

Exemple de code JS avec sortie - chaque URL est transformée en un tableau à 5 parties de ses "parties":

var re = /([a-z]+\:\/+)([^\/\s]*)([a-z0-9\-@\^=%&;\/~\+]*)[\?]?([^ \#]*)#?([^ \#]*)/ig; 
var str = 'Bob: Hey there, have you checked https://www.facebook.com ?\n(ignore) https://github.com/justsml?tab=activity#top (ignore this too)';
var m;

while ((m = re.exec(str)) !== null) {
    if (m.index === re.lastIndex) {
        re.lastIndex++;
    }
    console.log(m);
}

Vous donnera le suivant:

["https://www.facebook.com",
  "https://",
  "www.facebook.com",
  "",
  "",
  ""
]

["https://github.com/justsml?tab=activity#top",
  "https://",
  "github.com",
  "/justsml",
  "tab=activity",
  "top"
]

BAM! RegEx FTW!

4
Dan Levy

essayez (http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?

1
Vinit

J'ai nettoyé votre regex:

var urlexp = new RegExp('(http|ftp|https)://[a-z0-9\-_]+(\.[a-z0-9\-_]+)+([a-z0-9\-\.,@\?^=%&;:/~\+#]*[a-z0-9\-@\?^=%&;/~\+#])?', 'i');

Testé et fonctionne très bien;)

1
matthiasmullie

essayez cela a fonctionné pour moi

/^((ftp|http[s]?):\/\/)?(www\.)([a-z0-9]+)\.[a-z]{2,5}(\.[a-z]{2})?$/

c'est si simple et compréhensible

1
Tolga İskender

Essayez cette expression régulière pour plusieurs formats d'URL

/(([A-Za-z]{3,9})://)?([-;:&=\+\$,\w]+@{1})?(([-A-Za-z0-9]+\.)+[A-Za-z]{2,3})(:\d+)?((/[-\+~%/\.\w]+)?/?([&?][-\+=&;%@\.\w]+)?(#[\w]+)?)?/g
1
Khadijah J Shtayat

Le problème est que le "-" dans la classe de caractères (les crochets) est analysé comme une plage: [a-z] signifie "tout caractère compris entre a et z". Comme Vini-T l'a suggéré, vous devez échapper les caractères "-" dans les classes de caractères, en utilisant une barre oblique inverse.

0
PotatoEngineer