2014-01-23 3 views
1

У меня есть вход как google.com и список значений, какRegex - Match Pattern со списком значений

1. *.com 
2. *go*.com 
3. *abc.com 
4. *le.com 
5. *.* 

Мне нужно написать шаблон в Java, который должен вернуть все матчи, кроме *abc.com. Я пробовал несколько, но ничего не работало, как ожидалось. Незлая помощь. Заранее спасибо.

Update:

public static void main(String[] args) { 
     List<String> values = new ArrayList<String>(); 
     values.add("*.com"); 
     values.add("*go*.com"); 
     values.add("*abc.com"); 
     values.add("*le.com"); 
     values.add("*.*"); 
     String stringToMatch = "google.com"; 
     for (String pattern : values) { 
      String regex = Pattern.quote(pattern).replace("*", ".*"); 
      System.out.println(stringToMatch.matches(regex)); 
     } 
    } 

Выход:

false 
false 
false 
false 
false 

Я попытался это, но картина не соответствует.

+2

Разместить свои попытки пожалуйста. – Maroun

+0

Я могу сделать только обратное совпадение. т. е. ввод с * .com соответствует google.com –

ответ

1

Изменить эту строку в своем коде:

String regex = Pattern.quote(pattern).replace("*", ".*"); 

Для этого:

String regex = pattern.replace(".", "\\.").replace("*", ".*"); 
2

Вы можете преобразовать данные образцов в регулярные выражения, а затем использовать обычные функции регулярных выражений, как String.matches():

for (String pattern : patterns) { 
    final String regex = pattern.replaceAll("[\\.\\[\\](){}?+|\\\\]", "\\\\$0").replace("*", ".*"); 
    System.out.println(stringToMatch.matches(regex)); 
} 

редактирование: Видимо Pattern.quote() просто добавляет \Q...\E вокруг строки. Отредактировано для использования ручного цитирования.

редактировать 2: Другая возможность:

final String regex = Pattern.quote(pattern).replace("*", "\\E.*\\Q"); 
+0

Я попытался и обновил вопрос, но не работал как ожидалось. –

+0

@RajaAsthana Исправлено. – Njol

+0

что делает \\ E. * \\ Q do? Проблема теперь исправлена. –

2

Основываясь на previous answer of mine (читать комментарии вопроса, очень поучительный), вот метод wildcardsToRegex:

public static String wildcardsToRegex(String wildcards) { 

    String regex = wildcards; 

    // .matches() auto-anchors, so add [*] (i.e. "containing") 
    regex = "*" + regex + "*"; 
    // replace any pair of backslashes by [*] 
    regex = regex.replaceAll("(?<!\\\\)(\\\\\\\\)+(?!\\\\)", "*"); 
    // minimize unescaped redundant wildcards 
    regex = regex.replaceAll("(?<!\\\\)[?]*[*][*?]+", "*"); 
    // escape unescaped regexps special chars, but [\], [?] and [*] 
    regex = regex.replaceAll("(?<!\\\\)([|\\[\\]{}(),.^$+-])", "\\\\$1"); 
    // replace unescaped [?] by [.] 
    regex = regex.replaceAll("(?<!\\\\)[?]", "."); 
    // replace unescaped [*] by [.*] 
    regex = regex.replaceAll("(?<!\\\\)[*]", ".*"); 
    // return whether data matches regex or not 

    return regex; 

} 

Затем, в течение ваша петля, используйте:

for (String pattern : values) { 
    System.out.println(stringToMatch.matches(wildcardsToRegex(pattern))); 
} 
+0

Насколько это отличается от ответа Njol. Не могли бы вы объяснить. –

+1

@RajaAsthana Это * буквально * преобразует строку подстановочных знаков в регулярное выражение, в то время как решение @ Njol использует escape-последовательность '\ Q ... \ E' (подробнее об этом синтаксисе [здесь] (http: //www.regular- expression.info/characters.html), раздел «Специальные символы», последний §). Оба действительны. – sp00m

0

Вы можете использовать:

  List<String> values = new ArrayList<String>(); 
      values.add("*.com"); 
      values.add("*go*.com"); 
      values.add("*abc.com"); 
      values.add("*le.com"); 
      values.add("*.*"); 
      String stringToMatch = "google.com"; 
      for (String pattern : values) { 
       String regex = pattern.replaceAll("[.]", "\\.").replaceAll("[*]", "\\.\\*"); 
       System.out.println(stringToMatch.matches(regex)); 
      } 
Смежные вопросы