найти регулярное выражение для поиска по трем словам java

У меня есть запрос строки с двумя символами для алгоритма поиска. И у меня есть строка, состоящая из трех слов, разделенных запятой. Я хочу найти среди этих трех колясок.

например "Строка, Текст, Поиск"

если введено "Te", поиск должен совпадать, также должны совпадать "Str", "Se".

Я реализовал с помощью регулярного выражения. Но это работает только для первого слова. Обратите внимание, что у меня есть пробел перед вторым словом.

        stringInput="String, Text,Search";
        word="St";
        String pattern1=word+"\\w*,\\s\\w*,\\w";

        String pattern2="\\w*,\\."+word+"\\w*,\\w";

        String pattern3="\\w*,\\w*,"+word+"\\w";

        Pattern patternCompiled1=Pattern.compile(pattern1);
        Pattern patternCompiled2=Pattern.compile(pattern2);
        Pattern patternCompiled3=Pattern.compile(pattern3);
        Matcher matcher1= patternCompiled1.matcher(inputString);

        Matcher matcher2= patternCompiled2.matcher(inputString);

        Matcher matcher3= patternCompiled3.matcher(inputString);

            if(matcher1.find() || matcher2.find() || matcher3.find()){
                return true;
            }

Можете ли вы помочь мне, почему это не работает для второго и третьего слова?

Некоторые уточнения

Word1, String1, String2 Первый параметр всегда состоит из одного слова, Второй параметр может состоять из двух и более слов, а третий параметр из двух - это может быть несколько слов, разделенных пробелом. например. Текст, некоторый текст, другой текст Текст может быть любым текстом, некоторым, другим текстом, а также может содержать разные символы, я хочу выполнить поиск по первым буквам первого слова из каждого параметра.


person Jenya Kirmiza    schedule 18.07.2016    source источник
comment
Может быть, вы можете добавить необязательные пробелы \s* перед запятыми и использовать один String pattern1="(" + word+"\\w*,\\s*\\w*,\\s*\\w|\\w*,\\s*"+word+"\\w*,\\s*\\w|\\w*,\\s*\\w*,\\s*"+word+"\\w)";? См. ideone.com/w98knS.   -  person Wiktor Stribiżew    schedule 18.07.2016
comment
@WiktorStribiżew, пожалуйста, ознакомьтесь с разъяснениями в вопросе. Это классная идея, но мне нужно использовать что-то еще для второго и третьего параметра.   -  person Jenya Kirmiza    schedule 18.07.2016
comment
Нравится String pattern1="(" + word+"\\w*,\\s*\\w+(?:\\s+\\w+)?,\\s*\\w+(?:\\s+\\w+)*|\\w+,\\s*"+word+"\\w*(?:\\s+\\w+)?,\\s*\\w+(?:\\s+\\w+)*|\\w+,\\s*\\w+(?:\\s+\\w+)?,\\s*"+word+"\\w*(?:\\s+\\w+)*)";? (Та же ссылка)   -  person Wiktor Stribiżew    schedule 18.07.2016
comment
@WiktorStribiżew я имею в виду так: слово = КБ, КБ..., КБ...., КБ.... После КБ это может быть что угодно. Он может содержать такие символы, как - и все, кроме запятой.   -  person Jenya Kirmiza    schedule 18.07.2016
comment
А как насчет этого шаблона: (?=[\b\s]*)word?   -  person Maria Ivanova    schedule 18.07.2016
comment
Не могли бы вы разметить строку, используя запятую в качестве разделителя, и использовать, если string1.startsWith(SE)   -  person Souciance Eqdam Rashti    schedule 18.07.2016
comment
да, я могу, но это не самое быстрое решение   -  person Jenya Kirmiza    schedule 18.07.2016


Ответы (2)


Ваши шаблоны неверны. Я настоятельно рекомендую вам узнать больше о регулярном выражении:

Ваш первый шаблон: word+"\\w*,\\s\\w*,\\w" соответствует:

  • Строка для соответствия
  • За которым следует 0 или более символов слова
  • После запятой
  • За которым следует один пробел
  • За которым следует 0 или более символов слова
  • После запятой
  • За которым следует символ из одного слова

Этот шаблон работает для заданной входной строки, однако не будет работать, если после последней запятой есть пробел.

Второй шаблон: "\\w*,\\."+word+"\\w*,\\w" соответствует:

  • 0 или более символов слова
  • После запятой
  • За ним следует литерал .
  • Затем следует строка для соответствия
  • За которым следует 0 или более символов слова
  • После запятой
  • За которым следует символ из одного слова

Это не сработает, потому что вы экранировали символ . \\., что означает, что он будет соответствовать буквальному ., которого нет в вашей строке.

Ваш окончательный шаблон: "\\w*,\\w*,"+word+"\\w" соответствует:

  • 0 или более символов слова
  • После запятой
  • За которым следует 0 или более символов слова
  • После запятой
  • Затем следует строка для соответствия
  • За которым следует символ из одного слова

Это не удастся, потому что вы не учли пробелы после запятых.

Единственный правильный шаблон регулярного выражения будет выглядеть примерно так:

^(?:%s.*,.*,.*)|(?:.*,\\s*%s.*,.*)|(?:.*,.*,\\s*%s.*)$

Где %s — ваша строка для поиска.

Объяснение:

  • ^ соответствует началу строки, а $ — ее концу.
  • Есть три группы без захвата (?:)
  • Каждая группа разделена |, что означает или. Таким образом, только одна из этих групп должна совпадать.
  • Первая группа должна соответствовать искомому тексту в начале первого слова, то есть просто искомому тексту, за которым следует 0 или более любых символов, за которыми следует запятая, а затем 0 или более любых символов...
  • Вторая группа предназначена для сопоставления искомого текста в начале второго слова, это похоже на первый шаблон, за исключением того, что мы хотим сопоставить только пробел перед вторым словом, а не какой-либо символ.
  • Третья группа соответствует искомому тексту в начале третьего слова, этот шаблон почти такой же, как и второй, только сдвинутый вперед.

Использование:

String pattern = String.format("^(?:%s.*,.*,.*)|(?:.*,\\s*%s.*,.*)|(?:.*,.*,\\s*%s.*)$", 
            searchText, searchText, searchText);

Matcher m = Pattern.compile(pattern).matcher(stringInput);
System.out.println(m.find());

Однако существует более простое решение, не требующее сложного шаблона регулярного выражения.

Альтернативное решение (разбить на слова и проверить, не начинается ли оно с текста поиска):

private boolean anyWordStartsWith(final String words, final String search) {
    for (final String word : words.split("\\s*,\\s*")) {
        if(word.startsWith(search)) return true;
    }
    return false;
}

Альтернативное решение (Java 8):

boolean anyMatch = Arrays.stream(stringInput.split("\\s*,\\s*"))
                         .anyMatch(word -> word.startsWith(searchText));
person explv    schedule 18.07.2016
comment
if(stringInput.contains(text)) не соответствует моим потребностям. Видите ли, я хочу сопоставить начало первого слова. например Word1, Word1 ....., Word1 ....... Содержит даст мне, например. Содержит ai, не стоит в начале слова Содержит - person Jenya Kirmiza; 18.07.2016
comment
@JenyaKirmiza а, теперь я понимаю. - person explv; 18.07.2016

Для pattern2 \\. будет соответствовать символу точки, но на данный момент точки нет (вы можете просто использовать точку без \\ для соответствия любому символу)

Для pattern3 вы забыли ту же точку (или \\s, которую вы использовали в pattern1).

Так это должно выглядеть так:

String pattern1=word+"\\w*,\\s\\w*,\\w";
String pattern2="\\w*,."+word+"\\w*,\\w"; // Or replace dot with \\s
String pattern3="\\w*,.\\w*,"+word+"\\w"; //Same here

если вы хотите, чтобы он работал с stringInput="String, Text,Search";

person Asoub    schedule 18.07.2016
comment
смотрите комментарий Виктора Стрибижева он почти понял чего я хочу, его подход хорош - person Jenya Kirmiza; 18.07.2016
comment
Я вижу, это хорошо детализировано. Кроме того, почему вы использовали \\w* вместо .* ? Вы также могли бы разделить запятую (String.split()), удалить пробелы/пробелы и проверить их с помощью String.beginwith(word). Зависит от того, что вам нужно. ГЛ - person Asoub; 18.07.2016
comment
да, я знаю. я хотел сделать это с помощью регулярного выражения. - person Jenya Kirmiza; 18.07.2016