#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] )");