2013-07-27 14 views
6

Próbuję napisać funkcję, która wyodrębnia każde słowo z zdania zawierającego pewien podłańcuch np. Poszukiwanie "Po" w "Porky Pork Chop" zwróci Wieprzowinę Porky.Wyodrębnij każde pełne słowo zawierające pewien podłańcuch

Przetestowałem mój regex na regexpal, ale kod Java wydaje się nie działać. Co ja robię źle?

private static String foo() 
    { 

     String searchTerm = "Pizza"; 
     String text = "Cheese Pizza"; 

     String sPattern = "(?i)\b("+searchTerm+"(.+?)?)\b"; 
     Pattern pattern = Pattern.compile (sPattern); 
     Matcher matcher = pattern.matcher (text); 
     if(matcher.find()) 
     { 
      String result = "-"; 
      for(int i=0;i < matcher.groupCount();i++) 
      { 
       result+= matcher.group (i) + " "; 
      } 
      return result.trim(); 
     }else 
     { 
      System.out.println("No Luck"); 
     } 
    } 

Odpowiedz

2
  1. W Javie przekazać \bword boundaries do regex silnika trzeba zapisać go jako \\b. \b reprezentuje backspace w obiekcie String.

  2. Sądząc po przykładzie, chcesz zwrócić wszystkie słowa zawierające podłańcuch. Aby to zrobić, nie używaj for(int i=0;i < matcher.groupCount();i++), ale while(matcher.find()), ponieważ liczba grup będzie powtarzać się we wszystkich grupach w pojedynczej grze, a nie we wszystkich meczach.

  3. W przypadku ciąg może zawierać pewne znaki specjalne, to prawdopodobnie należy użyć Pattern.quote(searchTerm)

  4. w kodzie próbujesz znaleźć "Pizza" w "Cheese Pizza" więc zakładam, że chcemy także znaleźć sznurki w tym samym jako wyszukiwane podciąg . Chociaż twoje wyrwki będzie działało dobrze, możesz zmienić ostatnią część (.+?)?) na \\w*, a także dodać \\w* na początku, jeśli podciągi powinny być również dopasowane w środku słowa (nie tylko na początku).

więc kod może wyglądać

private static String foo() { 

    String searchTerm = "Pizza"; 
    String text = "Cheese Pizza, Other Pizzas"; 

    String sPattern = "(?i)\\b\\w*" + Pattern.quote(searchTerm) + "\\w*\\b"; 
    StringBuilder result = new StringBuilder("-").append(searchTerm).append(": "); 

    Pattern pattern = Pattern.compile(sPattern); 
    Matcher matcher = pattern.matcher(text); 
    while (matcher.find()) { 
     result.append(matcher.group()).append(' '); 
    } 
    return result.toString().trim(); 
} 
+0

To naprawdę świetne wyjaśnienie! Wielkie dzięki –

+0

@downvoter Czy możesz być tak miły i podzielić się powodem swojego działania? Nie mam nic przeciwko -1, kiedy na to zasłużyłem, więc nie lękajcie się. – Pshemo

2

Chociaż regex podejście jest z pewnością ważna metoda, I łatwiej przemyśleć kiedy rozdzielić słowa przez spacji. Można to zrobić za pomocą metody String 'split.

public List<String> doIt(final String inputString, final String term) { 
    final List<String> output = new ArrayList<String>(); 
    final String[] parts = input.split("\\s+"); 
    for(final String part : parts) { 
     if(part.indexOf(term) > 0) { 
      output.add(part); 
     } 
    } 
    return output; 
} 

Oczywiście nie warto nic robić, ponieważ skutecznie wykona dwa przejścia przez twój ciąg wejściowy. Pierwsze przejście do znalezienia znaków, które są białymi znakami do podziału, a drugie przejście do każdego podzielonego słowa na podłańcuch.

Jeśli jedno przejście jest konieczne, ścieżka regex jest lepsza.

+0

Jeśli może to być wiele spacji/linii końcowych, nadal możesz się dzielić z podziałem na '\\ s +'. – Thomas

+0

@Thomas dzięki, dodałem, że. :) –

1

Uważam, że odpowiedź nicholas.hauschild jest najlepsza.

Jednak jeśli naprawdę chciał użyć wyrażenia regularnego, można to zrobić w następujący sposób:

String searchTerm = "Pizza"; 
String text = "Cheese Pizza"; 
Pattern pattern = Pattern.compile("\\b" + Pattern.quote(searchTerm) 
     + "\\b", Pattern.CASE_INSENSITIVE); 
Matcher matcher = pattern.matcher(text); 
while (matcher.find()) { 
    System.out.println(matcher.group()); 
} 

wyjściowa:

Pizza 
1

Wzór powinien być

String sPattern = "(?i)\\b("+searchTerm+"(?:.+?)?)\\b"; 

Chcesz aby uchwycić cały ciąg (pizza). ?: zapobiega dwukrotnemu przechwyceniu części ciągu.

0

Spróbuj tego wzoru:

String searchTerm = "Po"; 
String text = "Porky Pork Chop oPod zzz llPo"; 

Pattern p = Pattern.compile("\\p{Alpha}+" + substring + "|\\p{Alpha}+" + substring + "\\p{Alpha}+|" + substring + "\\p{Alpha}+"); 

Matcher m = p.matcher(myString); 

while(m.find()) { 
    System.out.println(">> " + m.group()); 
} 
0

Ok, dam ci wzór w surowym stylu (nie Java styl, trzeba podwoić uciec się):

(?i)\b[a-z]*po[a-z]*\b 



I to wszystko .

Powiązane problemy