Регулярное выражение для :name, : othername, :other

#java #regex #language-agnostic

#java #регулярное выражение #язык не зависит

Вопрос:

Я пытаюсь получить все имена в строке, подобной этой:

 :name, :lastName
  

Но, похоже, я не нахожу правильного способа.

Это то, что я пробовал до сих пор:

 /^(:((w )(,:(w )) ).*)$/
  

В Java:

 Pattern a = Pattern.compile("(:((\w )(,:(\w )) ).*)");
Matcher m = a.matcher(":name,:lastName,:bd");
if( m.matches() ) { 
  for( int i = 0 ; i < m.groupCount() ; i   ) { 
    out.println( i   " = "   m.group( i ) );
  }   
}
  

Вывод:

 0 = :name,:lastName,:bd
1 = :name,:lastName,:bd
2 = name,:lastName,:bd
3 = name
4 = ,:bd
  

И я пытаюсь получить переменное количество групп, содержащих [name, lastName, bd]

Редактировать

Кстати, я пытаюсь получить это для более сложного регулярного выражения, соответствующего простым вещам, таким как:

  insert into table values ( :a, :b, :c )

/inserts intos (w )s valuess (( HERE IS MY QUESTION ))/
  

Комментарии:

1. @kaj: name, lastName, bd и так далее ( или group(n) = name, group(n 1) = LastName, group (n 2) = bd, group (n m) = etc )

2. Просто для пояснения: проблема в том, что повторяющиеся совпадения (\ w ) сохраняют только последнее совпадение, поэтому lastName кажется, что оно игнорируется. Я не знал этого раньше.

3. Я думаю, вам следует использовать какое-нибудь стандартное регулярное выражение для проверки первой части запроса (текстовой части), а затем использовать метод @MarcoS или @Aku для битов, которые начинаются с «:».

Ответ №1:

Обязательно ли размещать результат в разных группах? Это будет работать в противном случае:

 Pattern a = Pattern.compile(":([^,] )");
Matcher m = a.matcher(":name,:lastName,:bd");
while (m.find()) {
    System.out.println(m.group(1));
}
  

Редактировать: … и вы можете использовать split, если хотите получить массив результатов:

 String data = ":name,:lastName,:bd";
String[] parts = data.replace(":", "").split(",", -1);
System.out.println(Arrays.toString(parts));
  

Комментарии:

1. Нет, это не требование, мне просто нужно захватить их любым способом.

Ответ №2:

Возможно, вы хотите это:

 public static void main(String[] args) {
    Pattern a = Pattern.compile(":(\w )");
    Matcher m = a.matcher("insert into table values ( :a, :b, :c )");
    while (m.find()) {
        System.out.println(m.group(1));
    }
}
  

которое выводит:

 a
b
c
  

Комментарии:

1. Варианты.. да, извините, я пытаюсь поместить это в более сложное регулярное выражение: P

2. @MarcoS: Здесь нет необходимости использовать find(int) перегрузку; это для особых случаев, когда вам нужно начать поиск где-то еще, кроме начала строки. Метод без аргументов find() гарантированно возвращает все возможные неперекрывающиеся соответствия до тех пор, пока средство сопоставления не сбрасывается между вызовами.

3. @Алан Мур: ты прав! Спасибо! Я изменил свой код, а также использовал m.group(1) , который возвращает строки без :

Ответ №3:

 public static void main(String[] args)
{
    Pattern a = Pattern.compile(":([^,] )");
    Matcher m = a.matcher(":name,:lastName,:bd");
    while (m.find())
    {
        System.out.println(m.group(1));
    }

}
  

Ответ №4:

Регулярное выражение является сложным. Почему бы просто не split() это?

 String inputString = ":name,:lastName,:bd";

for (String s : inputString.split(",?:")) {
    System.out.println(s);
}
  

Комментарии:

1. @Oscar Я вижу. Я предпочитаю извлекать такие сложные фрагменты группами и уничтожать их по отдельности, а не пытаться свалить все это в общую кучу кошмара регулярных выражений. Это похоже на «класс бога».

2. Я тоже, но это сработало отлично: Pattern.compile(":([^,\s] )");