2015-04-13 4 views
2

У меня есть предложение и множество слов; Мэйуэзер, непобедимый ... и т.д. Я хочу:Используйте Java Regex, чтобы найти несколько подходящих слов в предложении

  1. проверить, если предложение содержит какое-либо из упомянутых выше слов ... (Я хочу, чтобы найти подходящие слова только, в основном игнорируют полные упоры, запятые и новые линии .)
  2. и если это произойдет, я хочу, чтобы отобразить несколько слов до и после каждого согласования слова, может быть, с помощью String.format()

Вот мой код, который, кажется, работает хорошо, но не совсем, как я хочу это:

String sentence = "Floyd Mayweather Jr is an American professional boxer " + 
      "currently undefeated as a professional and is a five-division world champion, " + 
      "having won ten world titles and the lineal championship in four different weight classes."; 

    String newText = ""; 
    Pattern p = Pattern.compile("(Mayweather) .* (undefeated)"); 
    Matcher m = p.matcher(sentence); 

    if (m.find()) { 
     String group1 = m.group(1); 
     String group2 = m.group(2); 

     newText = String.format("%s ... %s" , group1, group2); 
     System.out.println(newText); 
    } 

Выход сейчас:

Мэйвезер ... непобедимый

То, что я хочу что-то вроде этого:

Флойд Мэйуэзер-младший является американским ... в настоящее время undefeated как профессионал ...

Можете ли вы, пожалуйста, я знаю, как это сделать, или направлять меня в правильном направлении, потому что я застрял.

Спасибо заранее, ребята.

+0

Почему бы не использовать 'contains()' для проверки и 'replaceAll()' заменить? – TheLostMind

+0

Я не уверен, что вы имеете в виду, но я не хочу заменять текст в предложении, я хочу показать то же, но определенным образом. Если вы имели в виду что-то еще, пожалуйста, проясните это или покажите мне пример. Благодарю. –

ответ

2

Если вы действительно хотите решить эту проблему через RegEx, вам необходимо сделать ваши группы захвата соответствующими всем, что вы хотите вывести. В настоящее время они совпадают только условия поиска:

(Mayweather) .* (undefeated) 
// "Mayweather", "undefeated" 

Вы могли бы попробовать что-то вроде этого, но это будет соответствовать весь ваш пример (используя только одну группу!):

(.*Mayweather.*undefeated.*) 
// -whole text- 

Что можно было бы изменить это , чтобы соответствовать двум частям снова и не более 12 символов до и после (не используйте пробелы вокруг «совпадения всех» посередине и делайте это не жадным!):

(.{0,12}Mayweather.{0,12}).*?(.{0,12}undefeated.{0,12}) 
// "Floyd Mayweather Jr is an Am", "r currently undefeated as a profes" 

, которые могут быть доработаны остановиться на границах слов (результат нужно будет обрезать):

(\b.{0,12}Mayweather.{0,12}\b).*?(\b.{0,12}undefeated.{0,12}\b) 
// "Floyd Mayweather Jr is an ", " currently undefeated as a " 

Изменение этого вывести фиксированное число слов остается в качестве упражнения скучный читатель.

EDIT: Исправлена ​​жадность «. *» В последних двух версиях (добавлена ​​«?»).

+0

Кажется, что мы работаем, спасибо .. Остается крошечная вещь. Если я решит показать остальную часть предложения во втором матче, как я могу это сделать, например, _ "Флойд Мэйвезер-младший - это", "в настоящее время непобедимый как профессионал и пятикратный чемпион мира, выиграв ...." _ –

+0

@M_Y Вы можете использовать 'undefeated.* 'в этом случае для соответствия остальной части строки. Или 'undefeated [^.] * \.', Если вы уверены, что ваше предложение заканчивается периодом. – mkm13

+1

Спасибо, друг. Ваш ответ намного лучше, чем тот, который приведен ниже. Ваш ответ принят. –

0

Вы можете попробовать ниже одного,

Примечание: Это только прототип, так просто не скопировать и вставить его непосредственно

String str="Floyd Mayweather Jr is an American professional boxer currently undefeated as a professional and is a five-division world champion, having won ten world titles and the lineal championship in four different weight classes."; 
    int firstIndex=str.indexOf("American"); 
    int secondIndex=str.indexOf("boxer"); 
    String group1=str.substring(0,firstIndex+"American".length()); // gives you 1st group 

    String group2=str.substring(secondIndex); 
    String newText = String.format("%s ... %s" , group1, group2); 
    System.out.println(newText); 

Выход

Флойд Мэйвезер Jr является американским ... боксером в настоящее время непобедимым как профессионал и является чемпионом мира в пять дивизий, выиграв десять мировых титулов и линейный чемпионат в четырех разных категориях .

+0

Спасибо за ответ. Я просто попробовал свой код, и он отлично работает, когда слово находится в начале предложения, но если слово находится в конце или в конце длинного предложения, это вызывает проблему. например, если я выберу «мир» и «чемпионат» из приведенного выше предложения, тогда он отобразит весь текст с начала предложения, то есть «Флойд Мэйвезер-младший ...», и я хочу, чтобы он показывал несколько слов перед этим. Я Я попытаюсь поиграть с ним с моего конца, и если у вас есть другое решение, дайте мне знать, и я приму ваш ответ. Еще раз спасибо. –

+0

@M_Y, сказал вам, что это всего лишь прототип. Основная уловка в этой логике - найти индексы для создания групп, вы можете/должны улучшить эту логику! и я сохранил индекс как '0', как пример, вы можете использовать все, что хотите! –

0

Проблема с вашим кодом заключается в использовании групп. Группы регулярных выражений предоставляют строковые фрагменты, которые вы пытаетесь идентифицировать в первую очередь.

группа (0), также записанная как группа = вся строка.

группа (1) - ваш первый матч = первый экземпляр «Мэйвезер».

группа (2) - ваш второй матч = первый экземпляр «непобедимый».

Вы можете использовать старт (INT группы) и конечную (INT группы) методы в найти индексы ваших матчей, а затем выполнить основные операции со строками на новую строку.

Если вы собираетесь на использовании Regex специально, ваше решение будет выглядеть следующим образом:

 String sentence = ("Floyd Mayweather Jr is an American professional boxer " + 
        "currently undefeated as a professional and is a five-division       world champion, " + 
        "having won ten world titles and the lineal championship in four  different weight classes."); 

    /** Creates a StringBuilder, which can be altered, 
    * unlike a string, which is immutable. */ 
    StringBuilder sb = new StringBuilder(sentence.length()); 

    Pattern p = Pattern.compile("(Mayweather) .* (undefeated)"); 
    Matcher m = p.matcher(sentence); 

    if (m.find()) { 
     int g1Start = m.start(1); 
     int g1End = m.end(1); 

     int g2Start = m.start(2); 
     int g2End = m.end(2); 

     sb.append(sentence.substring(0, g1Start)); 
     sb.append("..."); 
     sb.append(sentence.substring(g1End, g2Start)); 
     sb.append("..."); 
     sb.append(sentence.substring(g2End, (sentence.length() - 1))); 

, и я не уверен, если вы нуждались в новой строки символ в конце, но если это так:

  sb.append("\r\n"); 

Тогда остальное просто:

  newText = sb.toString(); 
     textView.setText(newText); 
    } 

Надеюсь, это поможет :)

Смежные вопросы