2010-08-11 1 views
8

HTML-Code Beispiel:Wie Regular Expression verwenden, um die Zeichensatzzeichenfolge in HTML zu entsprechen?

<meta http-equiv="Content-type" content="text/html;charset=utf-8" /> 

Ich möchte RegEx verwenden, um die charset Informationen zu extrahieren (dh hier ist es "utf-8")

(Ich bin mit C#)

+0

Welche Sprache verwenden Sie? Sie alle haben feine (und nicht so subtile) Unterschiede in ihren RegEx-Dialekten. – Oded

+4

'Einige Leute denken, wenn sie mit einem Problem konfrontiert werden:" Ich weiß, ich werde reguläre Ausdrücke verwenden. " Jetzt haben sie zwei Probleme. ~ Jamie Zawinski –

+0

Wenn Ihr Beispiel HTML die Gesamtheit der Zeichenfolge ist, die Sie analysieren müssen, dann ist Regex in Ordnung, aber wenn Ihre Zeichenfolge ein ganzes HTML-Dokument ist, gilt "Sie ist" Antwort. – Benjol

Antwort

6

Diese Regex:

<meta.*?charset=([^"']+) 

funktionieren sollte. Verwenden Sie einen XML-Parser zum Extrahieren ist Overkill.

+0

Hm ... ' '. Gib mir einen HTML-Parsing Regex, und ich werde es brechen. – You

+0

@You Dies ist ein erfundenes Nicht-Beispiel, das in der Praxis fast nie vorkommen würde. – NullUserException

+0

Ich bin glücklich, dass meine Regex 99,9% der Zeit funktioniert. Übrigens, Sie können nicht immer einen XML-Parser verwenden, da sich echtes Markup-Verhalten selten gut verhält. – NullUserException

0

I versucht mit Javascript Platzieren Sie Ihre Zeichenfolge in eine Variable und eine Übereinstimmung:

var x = '<meta http-equiv="Content-type" content="text/html;charset=utf-8" />'; 
var result = x.match(/charset=([a-zA-Z0-9-]+)/); 
alert(result[1]); 
+1

Oh nein, '

Ein Absatz, der charset=bogus enthält!

'. – You

+0

Nun, richtig. Ich betrachtete die Zeichenfolge, die nur das -Tag enthält. – Zsolti

-1

Don't use regular expressions to parse (X)HTML! Verwenden Sie ein geeignetes Werkzeug, d. H. Einen SGML- oder XML-Parser. Ihr Code sieht wie XHTML aus, also würde ich einen XML-Parser ausprobieren. Nach dem Abrufen des Attributs aus dem Meta-Element jedoch; eine Regex wäre angemessener. Obwohl, nur eine Zeichenfolge aufgeteilt auf ; würde sicherlich den Trick (und schneller, auch) tun.

+0

Er analysiert nicht ein ganzes HTML-Dokument, nur eine einzelne Zeile. – Oded

+0

Ich sehe das nicht in der ursprünglichen Frage. –

+1

Sagt das nirgends. Und die Regel "no regex" gilt immer noch, sogar für einzelne Zeilen; (X) HTML ist keine reguläre Grammatik und kann nicht mit regulären Ausdrücken analysiert werden. – You

0

Für PHP:

$charset = preg_match('/charset=([a-zA-Z0-9-]+)/', $line); 
$charset = $charset[1];
+1

-1, mit Regexps ist keine gute Idee. Siehe meinen Kommentar zur Antwort von @Zsolti. – You

0

Ich stimme eher mit @You aber ich gebe Ihnen die Antwort, die Sie anfordern, plus einige andere Lösungen.

 String meta = "<meta http-equiv=\"Content-type\" content=\"text/html;charset=utf-8\" />"; 
     String charSet = System.Text.RegularExpressions.Regex.Replace(meta,"<meta.*charset=([^\\s'\"]+).*","$1"); 

     // if meta tag has attributes encapsulated by double quotes 
     String charSet = ((meta.Split(new String[] { "charset=" }, StringSplitOptions.None))[1].Split('"'))[0]; 
     // if meta tag has attributes encapsulated by single quotes 
     String charSet = ((meta.Split(new String[] { "charset=" }, StringSplitOptions.None))[1].Split('\''))[0]; 

So oder so eine der oben sollte ohne sich vorher vergewissert gefährlich sein arbeiten, aber auf jeden Fall die String.Split Befehle können, um zu sehen, ob die Array-Daten hat, so möchten vielleicht sonst die oben ausbrechen werden Sie bekommen eine NullException.

0

Meine regex:

<meta[^>]*?charset=([^"'>]*) 

Mein Testfall:

<meta http-equiv="Content-type" content="text/html;charset=utf-8" /> 
<meta name="author" value="me"><!-- Maybe we should have a charset=something meta element? --><meta charset="utf-8"> 

C# -Code:

using System.Text.RegularExpressions; 
string resultString = Regex.Match(sourceString, "<meta[^>]*?charset=([^\"'>]*)").Groups[1].Value; 

RegEx-Beschreibung:

// <meta[^>]*?charset=([^"'>]*) 
// 
// Match the characters "<meta" literally «<meta» 
// Match any character that is not a ">" «[^>]*?» 
// Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?» 
// Match the characters "charset=" literally «charset=» 
// Match the regular expression below and capture its match into backreference number 1 «([^"'>]*)» 
// Match a single character NOT present in the list ""'>" «[^"'>]*» 
//  Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*» 
+0

Ich werde auch dieses brechen, weil mir langweilig ist: ' ' – You

0

Dieser reguläre Ausdruck wird der charset Wert sich von jedem Meta-Tag erfassen:

(?<=([<META|<meta])(.*)charset=)([^"'>]*) 

Beispiel Eingabe:

<meta http-equiv=Content-Type content="text/html; charset=windows-1252"> 
<meta http-equiv=Content-Type content=text/html; charset=windows-1252> 
<meta http-equiv=Content-Type content='text/html; charset=windows-1252'> 
<meta http-equiv="Content-type" content="text/html;charset=utf-8" /> 
<meta http-equiv="Content-type" content="text/html;charset=iso-8859-1" /> 

es wie folgt verwendet:

Regex regexObj = new Regex("(?<=<meta(.*)charset=)([^\"'>]*)", RegexOptions.IgnoreCase); 
Match matchResults = regexObj.Match(subjectString); 
while (matchResults.Success) { 
    for (int i = 1; i < matchResults.Groups.Count; i++) { 
     Group groupObj = matchResults.Groups[i]; 
     if (groupObj.Success) { 
      // matched text: groupObj.Value 
      // match start: groupObj.Index 
      // match length: groupObj.Length 
     } 
    } 
    matchResults = matchResults.NextMatch(); 
} 

diese finden Werte:

windows-1252

windows-1252

windows-1252

utf-8

iso-8859-1

14

Meine Antwort liefert eine robustere Version von @ Floyd und dem Grad möglich, Adressen @ Sie die Bruchtestfall, wo Ein negativer Lookahead wird verwendet, um dies zu vermeiden. Es gibt wirklich nur einen relevanten Fall, den ich mir vorstellen kann (eine Variante von @ You's Beispiel), wo es ein falsches positives gibt, aber ich denke, es wäre ziemlich selten. Es wird erwartet, dass Ausdrücke mit dem Flag "case-insensitive" ausgeführt werden und mit java.util.regex und JRegex getestet wurden.

Capture-Gruppen werden automatisch abgeschnitten und enthalten keine Anführungszeichen oder andere Tag-Zeichen wie "/" oder ">". Im zweiten Ausdruck gibt es 2 Capture-Gruppen; der erste ist der Wert vom Inhaltstyp, der leer sein kann (dh wenn charset attribute verwendet wird), und der zweite ist der Zeichensatzwert, der immer nicht leer sein wird (es sei denn, der Zeichensatzwert wird aus irgendeinem Grund buchstäblich leer gelassen)).

Regex für den Abgleich/Gruppierung charset Wert - nur getrimmt, überspringt Zitate

<meta(?!\s*(?:name|value)\s*=)[^>]*?charset\s*=[\s"']*([^\s"'/>]*) 

Wie oben, aber auch Spiele/Gruppen-Content-Type (optional) und charset (erforderlich) Werte, getrimmt, überspringt Anführungszeichen . Minor Nachteil - Misses eigenständigen Inhaltstyp Wert übereinstimmt, das heißt "text/html"

<meta(?!\s*(?:name|value)\s*=)(?:[^>]*?content\s*=[\s"']*)?([^>]*?)[\s"';]*charset\s*=[\s"']*([^\s"'/>]*) 

Testfälle (Allpaß mit Ausnahme der allerletzten) ...

<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/> 
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" /> 
<meta http-equiv='Content-Type' content='text/html;charset=iso-8859-1'/> 
<meta http-equiv='Content-Type' content='text/html;charset=iso-8859-1' /> 
<meta http-equiv=Content-Type content=text/html;charset=iso-8859-1/> 
<meta http-equiv=Content-Type content=text/html;charset=iso-8859-1 /> 
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> 
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" > 
<meta http-equiv='Content-Type' content='text/html;charset=iso-8859-1'> 
<meta http-equiv='Content-Type' content='text/html;charset=iso-8859-1' > 
<meta http-equiv=Content-Type content=text/html;charset=iso-8859-1> 
<meta http-equiv=Content-Type content=text/html;charset=iso-8859-1 > 

<meta http-equiv="Content-Type" content="text/html;charset='iso-8859-1'"> 
<meta http-equiv="Content-Type" content="'text/html;charset=iso-8859-1'"> 
<meta http-equiv="Content-Type" content="'text/html';charset='iso-8859-1'"> 
<meta http-equiv='Content-Type' content='text/html;charset="iso-8859-1"'> 
<meta http-equiv='Content-Type' content='"text/html;charset=iso-8859-1"'> 
<meta http-equiv='Content-Type' content='"text/html";charset="iso-8859-1"'> 

<meta http-equiv="Content-Type" content="text/html;;;charset=iso-8859-1"> 
<meta http-equiv="Content-Type" content="text/html;;;charset='iso-8859-1'"> 
<meta http-equiv="Content-Type" content="'text/html;;;charset=iso-8859-1'"> 
<meta http-equiv="Content-Type" content="'text/html';;;charset='iso-8859-1'"> 
<meta http-equiv='Content-Type' content='text/html;;;charset=iso-8859-1'> 
<meta http-equiv='Content-Type' content='text/html;;;charset="iso-8859-1"'> 
<meta http-equiv='Content-Type' content='"text/html;;;charset=iso-8859-1"'> 
<meta http-equiv='Content-Type' content='"text/html";;;charset="iso-8859-1"'> 

<meta http-equiv = " Content-Type " content = " ' text/html ' ; ;; ' ; ' ' ; ' ; ' ;; ; charset = ' iso-8859-1 ' " > 
<meta content = " ' text/html ' ; ;; ' ; ' ' ; ' ; ' ;; ; charset = ' iso-8859-1 ' " http-equiv = " Content-Type " > 
<meta http-equiv = Content-Type content = text/html;charset=iso-8859-1 > 
<meta content = text/html;charset=iso-8859-1 http-equiv = Content-Type > 
<meta http-equiv = Content-Type content = text/html ; charset = iso-8859-1 > 
<meta content = text/html ; charset = iso-8859-1 http-equiv = Content-Type > 
<meta http-equiv = Content-Type content = text/html ;;; charset = iso-8859-1 > 
<meta content = text/html ;;; charset = iso-8859-1 http-equiv = Content-Type > 
<meta http-equiv = Content-Type content = text/html ; ; ; charset = iso-8859-1 > 
<meta content = text/html ; ; ; charset = iso-8859-1 http-equiv = Content-Type > 

<meta charset="utf-8"/> 
<meta charset="utf-8" /> 
<meta charset='utf-8'/> 
<meta charset='utf-8' /> 
<meta charset=utf-8/> 
<meta charset=utf-8 /> 
<meta charset="utf-8"> 
<meta charset="utf-8" > 
<meta charset='utf-8'> 
<meta charset='utf-8' > 
<meta charset=utf-8> 
<meta charset=utf-8 > 

<meta charset = " utf-8 " > 
<meta charset = ' utf-8 ' > 
<meta charset = " utf-8 ' > 
<meta charset = ' utf-8 " > 
<meta charset = " utf-8  > 
<meta charset = ' utf-8  > 
<meta charset =  utf-8 ' > 
<meta charset =  utf-8 " > 
<meta charset =  utf-8  > 
<meta charset =  utf-8 /> 

<meta name="title" value="charset=utf-8 — is it really useful (yep)?"> 
<meta value="charset=utf-8 — is it really useful (yep)?" name="title"> 
<meta name="title" content="charset=utf-8 — is it really useful (yep)?"> 
<meta name="charset=utf-8" content="charset=utf-8 — is it really useful (yep)?"> 

<meta content="charset=utf-8 — is it really useful (nope, not here, but gotta admit pretty robust otherwise)?" name="title"> 
0

Versuchen Sie auch:

<meta(?!\s*(?:name|value)\s*=)[^>]*?charset\s*=[\s"']*([a-zA-Z0-9-]+)[\s"'\/]*>