2010-12-10 11 views
2

Ich versuche Regex Muster für eine Klasse zu lernen. Ich mache einen einfachen HTML-Lexer/Parser. Ich weiß, dass dies nicht der beste oder effizienteste Weg ist, um einen Lexer/Parser zu erstellen, aber es ist nur um Regex-Muster zu verstehen.Wie erstelle ich ein Regex-Muster für HTML-Simple-Text?

Also meine Frage ist: Wie erstelle ich ein Muster, das, wenn der String keine HTML-Tags enthält nicht überprüft (dh <TAG>) und enthält keine HTML-Entities (dh &ENT;)?

Dies ist, was ich mit so weit kommen könnte, aber es immer noch nicht funktioniert:

.+?(^(?:&[A-Za-z0-9#]+;)^(?:<.*?>)) 

EDIT: Das einzige Problem ist, dass ich nicht das Endergebnis ein Ich brauche negieren zu finden vollständiges Muster, das diese Aufgabe erfüllen würde, wenn es möglich ist, obwohl es möglicherweise nicht hübsch ist. Ich habe das nie erwähnt, aber es sollte ziemlich genau mit jedem einfachen Text in einer HTML-Seite übereinstimmen.

+0

möglich Duplikat [RegEx Spiel offen Tags außer XHTML self-contained tags] (http://stackoverflow.com/questions/1732348/regex-match-open -tags-except-xhtml-inclosed-tags) –

+0

Warum können Sie das Muster nicht negieren? Ich verstehe Ihre Argumentation nicht ... –

+0

Sie könnten Ihre HTML-Zeichenfolge kopieren und dann die unten stehenden Regex-Muster verwenden, um die HTML-Tags und -Entitäten loszuwerden (ersetzen Sie die Muster durch nichts). Dadurch bleiben Sie mit reinem Text (obwohl die Entitäten weg sind, anstatt in ihre tatsächlichen Zeichen übersetzt). –

Antwort

1

Wenn Sie nach Strings suchen, die NICHT einem Muster folgen, ist es am einfachsten, das Muster zu vergleichen und dann das Ergebnis des Tests zu negieren.

<[^>]+>|&[^;]+; 

Jede Zeichenfolge, die dieses Muster mindestens einen Tag haben Spiele werden (wie Sie es definiert haben) oder juristische Person (wie Sie es definiert haben). Daher sind die Zeichenfolgen, die Sie möchten, Zeichenfolgen, die NICHT mit diesem Muster übereinstimmen (sie haben KEINE Tags oder Elemente).

+0

Ich würde beide '*' in ein '+' ändern und die einfangende Gruppe entfernen. – aioobe

+0

Guter Punkt. Fest. –

+0

Wäre das möglich?^(<[^>] +> | &[^;] +;) –

2

Sie könnten den Ausdruck <.+?>|&.+?; verwenden, um nach einer Übereinstimmung zu suchen, und dann das Ergebnis negieren.

  • <.+?> sagt zuerst eine < dann etwas (ein oder mehrere Male), dann ein >
  • &.+?; sagt zuerst ein & dann etwas (ein oder mehrere Male), dann ein ;

Hier ist ein vollständiges Beispiel mit einem ideone.com demo here.

import java.util.regex.*; 

public class Test { 
    public static void main(String[] args) { 
     String[] tests = { "hello", "hello <b>world</b>!", "Hello&nbsp;world" }; 
     Pattern p = Pattern.compile("<.+?>|&.+?;"); 
     for (String test : tests) { 
      Matcher m = p.matcher(test); 
      if (m.find()) 
       System.out.printf("\"%s\" has HTML: %s%n", test, m.group()); 
      else 
       System.out.printf("\"%s\" does have no HTML%n", test); 
     } 
    } 
} 

Ausgang:

"hello" does have no HTML 
"hello <b>world</b>!" has HTML: <b> 
"Hello&nbsp;world" has HTML: &nbsp; 
Verwandte Themen