2016-09-21 12 views
2

Ich habe zwei URLs und muss eine Zeichenfolge nach Domain-Erweiterung erfassen, wenn es eine zwei Zeichen lange Zeichenfolge ist und es endet mit einem "/". Bisher habe ich diese bekam:Regex entspricht einer Untergruppe, die mit einem "/" endet

var t1 = "http://www.test.net/shop/test-3"; 
var t2 = "http://www.test.net/gb/shop/test-2"; 

var rgx = /\.([a-z]{0,3})\/([a-z]{2}\/)?/; 



console.log(rgx.exec(t1)); 

console.log(rgx.exec(t2)); 

Es spuckt

[".net/", "net", undefined] 
[".net/gb/", "net", "gb/"] 

was richtig ist, es sei denn ich will stattdessen nicht erfassen „gb /“, sondern „gb“. Irgendwelche Ideen? Ich bin ganz fest ..

Antwort

0

Sie können einfach den Schrägstrich als lookahead verwenden, die es nicht wie in der Capture-Gruppe (?=\/)

EDIT so gesetzt werden: als Evaldas Raisutis in einem Kommentar erwähnt, wird dies die beiden Zeichen nicht übereinstimmen, wenn die zwei Zeichen sind die letzte Sache in der URL und es gibt keinen abschließenden Schrägstrich, also kann stattdessen (?=\/|$) verwendet werden, das ein /oder das Ende der Linie entspricht und macht diesen Teil folglich optional. Welche verwandelt Ihr Muster in

\.([a-z]{0,3})\/([a-z]{2}(?=\/|$))? 

See in Regex101

var t1 = "http://www.test.net/shop/test-3"; 
 
var t2 = "http://www.test.net/gb/shop/test-2"; 
 
var t3 = "http://www.test.net/de/"; 
 
var t4 = "http://www.test.net/fr"; 
 

 
var rgx = /\.([a-z]{0,3})\/([a-z]{2}(?=\/|$))?/; 
 

 
console.log(rgx.exec(t1)); 
 
console.log(rgx.exec(t2)); 
 
console.log(rgx.exec(t3)); 
 
console.log(rgx.exec(t4));

+0

Also, irgendeinen Kommentar für den Downvote? – vlaz

+0

Nicht sicher, warum die down-Stimmen, aber ich habe damit endete. Außer es stellte sich heraus, dass ich auch den Schrägstrich optional machen musste, also mit /\.([az]{0,3})\/([az]{2}(?=\/|$))?/ –

+0

fertig @EvaldasRaisutis ja, wenn du andere nach dem zweistelligen Code hast, hätte der obige Regex funktioniert, aber nicht, wenn es das letzte in der URL ist. Ich füge das nur zur besseren Sichtbarkeit hinzu. – vlaz

6

Eine Technik, die Sie verwenden können, um die Erfassungsgruppe innerhalb einer optionalen Nicht-Erfassung Gruppe mit:

/\.([a-z]{0,3})\/(?:([a-z]{2})\/)?/ 
       ^^^^   ^^ 

Siehe regex demo

var t1 = "http://www.test.net/shop/test-3"; 
 
var t2 = "http://www.test.net/gb/shop/test-2"; 
 
console.log(/\.([a-z]+)\/(?:([a-z]{2})\/)?/.exec(t1)); 
 
console.log(/\.([a-z]+)\/(?:([a-z]{2})\/)?/.exec(t2));

Sprechen über alternative Ansätze, scheint diese Regex sicherer, wie es genauer ist:

/^https?:\/\/[^\/]+\.([a-z]+)\/(?:([a-z]{2})\/)?/ 

Siehe this regex demo

Einzelheiten:

  • ^ - Beginn der Zeichenfolge
  • https?:\/\/ - ein protocal Teil (http:// oder https://)
  • [^\/]+\.([a-z]+)\/ - die Domäne Teil eines passenden oder mehr Zeichen oth er als / dann . und dann die Erfassung der TLD (1 oder mehr Buchstaben, [a-z]+) in Gruppe 1
  • (?:([a-z]{2})\/)? - eine optionale Sequenz von:
    • ([a-z]{2}) - Gruppe 2 Einfangen 2 Klein ASCII Buchstaben
    • \/ - ein Schrägstrich.

var t1 = "http://www.test.net/shop/test-3"; 
 
var t2 = "http://www.test.net/gb/shop/test-2"; 
 
console.log(/^https?:\/\/[^\/]+\.([a-z]+)\/(?:([a-z]{2})\/)?/.exec(t1)); 
 
console.log(/^https?:\/\/[^\/]+\.([a-z]+)\/(?:([a-z]{2})\/)?/.exec(t2));

+0

ich mit der Suche nach dem ersten '/' und gehen von dort zustimmen. Es ist in der Tat viel genauer. Eine Sache, die ich nur beachten würde ist, dass der Domain-Name mehr als drei Zeichen haben könnte ('domain.info'), also würde ich diese Einschränkung entfernen. Angenommen, eine URL wird geparst (im Gegensatz zu Freitext), dann wollen wir wirklich nur alles zwischen dem letzten '.' und vor dem ersten'/'. Das ist _if_ die TLD ist sogar relevant - wenn es nicht ist, dann reicht es einfach alles nach dem ersten und zweiten '/' zu bekommen. Auch wenn es ohne Regex noch einfacher ist. – vlaz

+0

@vlaz: Vielen Dank für einen wertvollen Kommentar, ich habe die Antwort aktualisiert. Es kann auch andere Verbesserungen geben, ich weiß einfach nicht, ob OP sie hier braucht :) –

+0

Richtig, je nach Anwendungsfall könnte es ein Overkill sein. – vlaz

4

Ein weiterer Ansatz aus der Zeichenfolge, die das erste Element nach der Domain-Endung zu analysieren wäre:

function parse(str){ 
 
    // Remove the domain extension and everything before that. 
 
    // Then return the first section of the rest, before `/` 
 
    return str.replace(/.+\.\w+\//, '') 
 
       .split('/')[0]; 
 
} 
 
console.log(parse("http://www.test.net/shop/test-3")); 
 
console.log(parse("http://www.test.net/gb/shop/test-2")); 
 
console.log(parse("http://www.test.net/nl"));

Auf diese Weise können Sie einfach die Länge der zurückgegebenen Ergebnisse überprüfen.

Regex Erklärung:

.+\.\w+\/ 
.+ - matches any character (except newline) 
      Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy] 
\. - matches the character . literally 
\w+ - match any word character [a-zA-Z0-9_] 
      Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy] 
\/ - matches the character/literally 

Diese Regex greift im Grunde alles, was vor der Domain-Erweiterung, die Domain-Endung selbst und die / dahinter.

Verwandte Themen