2013-08-04 8 views
8

I Liste der Schlüsselwörter müssen passt durch den Benutzer eingegeben und können sie enthält die Sonderzeichen wie $, #, @, ^, &, usw.Java Regular Expression Exact Wort mit Sonderzeichen

Wie pro meine Anforderung wann immer ich Liste von Textnachrichten empfangen i müssen nach allen Schlüsselwörtern in jeder Nachricht suchen.

Wir müssen genau passendes Keyword entsprechen.

FALL 1: Einfache Keyword - Simple Message

verwendete ich \b genaue Stichwort passen und es arbeitet in Ordnung.

public static void main(String[] args) { 
     String patternStr = "(?i)\\bHello\\b"; 

     Pattern pattern = Pattern.compile(patternStr); 

     List<String> strList = new ArrayList<String>(); 
     strList.add("HHello Message"); 
     strList.add("This is Hello Message "); 
     strList.add("Now Hellos again."); 

     for(String str : strList) { 
      Matcher matcher = pattern.matcher(str); 
      System.out.println(">> "+matcher.find()); 
     } 
    } 

OUTPUT Erwartet als

>> false 
>> true 
>> false 

FALL 2: Einfache Keyword - Nachricht mit Sonderzeichen

Nun, wenn ich über denselben Code ausführen für Nachrichten dann folgende hat nicht funktioniert wie erwartet.

List<String> strList = new ArrayList<String>(); 
strList.add("#Hello Message"); 
strList.add("This is Hello Message "); 
strList.add("Now Hellos again."); 

OUTPUT:

true 
true 
false 

erwartete Ausgabe

false 
true 
false 

FALL 3: Stichwort & Nachricht mit Sonderzeichen

Wenn ich folgende Nachrichten erhalte und das Schlüsselwort lautet #Hello. Ich schrieb folgenden Code, aber es hat nicht funktioniert.

public static void main(String[] args) { 
     String patternStr = "(?i)\\b#Hello\\b"; 

     Pattern pattern = Pattern.compile(patternStr); 

     List<String> strList = new ArrayList<String>(); 
     strList.add("HHello Message"); 
     strList.add("This is #Hello Message "); 
     strList.add("Now Hellos again."); 

     for(String str : strList) { 
      Matcher matcher = pattern.matcher(str); 
      System.out.println(">> "+matcher.find()); 
     } 
    } 

OUTPUT:

>> false 
>> false 
>> false 

erwartete Ausgabe:

>> false 
>> true 
>> false 

Wie kann ich die Sonderzeichen entkommen und CASE 2 and CASE 3 lösen.

Bitte helfen.

+1

Eine Wortgrenze bedeutet keine Raumgrenze. Hier sind Sie verwirrt. – tchrist

Antwort

3

Fall 2 scheint das Gegenteil wie Fall 3, so glaube ich nicht, dass Sie die Pattern s kombinieren können.

Für Fall 2 Ihre Pattern könnte wie folgt aussehen:

Pattern pattern = Pattern.compile("(\\s|^)Hello(\\s|$)", Pattern.CASE_INSENSITIVE); 

In diesem Fall haben wir das Stichwort Leerzeichen oder Anfang/Ende der Eingangs umgeben.

Für Fall 3, Ihre Pattern könnte wie folgt aussehen:

Pattern pattern = Pattern.compile("[\\$#@\\^&]Hello(\\s|$)", Pattern.CASE_INSENSITIVE); 

In diesem Fall haben wir das Stichwort mit einem des Sonderzeichen Ihrer Wahl (man beachte die entkam reservierten Zeichen $ und ^) vorausgehen, dann Wir akzeptieren Whitespace oder das Ende der Eingabe als Zeichen nach dem Schlüsselwort.

+0

Ich kombinierte beide Muster wie folgt Pattern.compile ("(\\ s | ^)" + Pattern.quote (Phrase) + "(\\ s | $)", Pattern.CASE_INSENSITIVE); und es hat funktioniert !!! –

2

Verwenden (?:^|\s) ("start of text oder Leerzeichen") anstelle der ersten \b und (?:$|\s) ("Ende des Textes oder Leerzeichen") anstelle der zweiten \b in Ihrem regex.

+0

Danke für die Erklärung –

1

Das Problem kommt von der Art, wie "genaues Wort" definiert ist. Es ist nicht nur ein Leerzeichen, das das Wort umschließen kann, um es zu einem Wort zu machen. Zum Beispiel würde man in den meisten Fällen eine exakte Wortübereinstimmung für 'Hallo' wünschen.

"hallo da", "Dieser junge Mann sagte gerade Hallo zu diesem anderen jungen Mann" und "Ich wünschte, die Leute würden immer noch ans Telefon gehen, indem sie Ahoi anstatt Hello sagen."

Wenn Sie wollen, dass die Übereinstimmung nur auf Whitespace aufgeteilt wird, dann glaube ich, dass Sie die Whitespace-Bedingung angeben müssen. Angenommen, Sie möchten auch, dass es am Ende übereinstimmt, dann würde ich so etwas vorschlagen.

Pattern pattern = Pattern.compile("\(^\| \)" + escapeSearchString(patternString) + "\(\|$\)"); 

und dann haben ein paar Methoden wie diese

public String escapeSearchString(String patternString) { 
    StringBuilder stringBuilder = new StringBuilder(patternString.length() * 3); 
    for (char c : patternString.toCharArray()) { 
     if (isEscapableCharacter(c)) { 
      stringBuilder.append("\\"); 
     } 
     stringBuilder.append(c); 
    } 
} 

public boolean isEscapableCharacter(char c) { 
    switch (c) { 
     case '#': 
     case '$': 
     case '@': 
     case '^': 
     case '&': 
      return true; 
     default: 
      return false; 
    } 
} 

wäre es wahrscheinlich besser, ein Zeichen iterieren [] für die escapable Zeichen und sie aus einer Konfigurationsdatei laden.

1

vielleicht versuchen auf diese Weise

String patternStr = "(?i)(?<=\\s|^)"+Pattern.quote(searchedStubstring)+"(?=\\s|$)"; 

(? < = ...) und (? = ...) positiv look behind and ahead so wird es prüfen, ob vor Ihrer searchedStubstring

  • haben Leerraum \\s oder Start des Eingangs ^ vor, und
  • Leerraum \\s oder Ende des Eingangs & danach.

Auch im Fall möchten Sie für Sonderzeichen wie $+ und andere, die Sie ihnen entkommen müssen gesucht.Um dies zu tun Sie Pattern.quote(searchedStubstring)

0

zum Beispiel verwenden können, wenn Ihr Wort spezielle Zeichen haben wollen (zum Beispiel hier ‚#‘) am Anfang und Ende dieser Sie schreiben haben die folgenden:

Pattern p = Pattern.compile("(\\s|^|#)"+word+"(\\s|\\#|$)", Pattern.CASE_INSENSITIVE); 

Wenn Sie eine exakte Übereinstimmung wünschen:

Pattern p = Pattern.compile("(\\s|^)"+word+"(\\s|$)", Pattern.CASE_INSENSITIVE); 

mit '|' ist wie oder so können Sie als Spiel speziellen Chars Sie ..für Beispiel hinzufügen:

Pattern p = Pattern.compile("(\\s|^|#|:|-)"+word+"(\\s|\\#|\\,|\\.|$)", Pattern.CASE_INSENSITIVE); 

char ‚^‘ die Zeichenfolge am Anfang der Zeile und ‚$‘ bedeutet, am Ende der Linie zu erkennen. siehe hier: Summary of regular-expression constructs