У меня есть строка поиска. Когда он содержит символ доллара, я хочу захватить все последующие символы, но не включать точку или последующий символ доллара. Последний будет представлять собой последующее совпадение. Итак, для любой из этих поисковых строк ...:
"/bla/$V_N.$XYZ.bla";
"/bla/$V_N.$XYZ;
Я бы хотел вернуться:
- V_N
- XYZ
Если строка поиска содержит символы процента, я также хочу вернуть то, что находится между парой символов%.
Следующее регулярное выражение, похоже, помогает в этом.
"%([^%]*?)%";
Вывод:
- Начинайте и заканчивайте с%,
- Создайте группу захвата - ()
- иметь класс символов, содержащий что-либо, кроме символа% (каретка означает не символ)
- повторил - но не жадно *?
Если некоторые языки позволяют использовать %1
, %2
для групп захвата, Java вместо этого использует синтаксис backslash\number
. Итак, эта строка компилируется и генерирует вывод.
Я подозреваю, что символ доллара и точка нужно экранировать, поскольку они являются специальными символами:
$
- обычно конец строки.
- это метапоследовательность для любого символа.
Я пробовал использовать символы двойной обратной косой черты .. \
- Оба как классы персонажей.
[^\\.\\$%]
- и используя запись OR'd
%|\\$
в попытках объединить эту логику и, кажется, не может получить ничего, чтобы играть в мяч.
Интересно, сможет ли еще одна пара глаз увидеть, как решить эту загадку!
Мои попытки до сих пор:
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
public static void main(String[] args) {
String search = "/bla/$V_N.$XYZ.bla";
String pattern = "([%\\$])([^%\\.\\$]*?)\\1?";
/* Either % or $ in first capture group ([%\\$])
* Second capture group - anything except %, dot or dollar sign
* non greedy group ( *?)
* then a backreference to an optional first capture group \\1?
* Have to use two \, since you escape \ in a Java string.
*/
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(search);
List<String> results = new ArrayList<String>();
while (m.find())
{
for (int i = 0; i<= m.groupCount(); i++) {
results.add(m.group(i));
}
}
for (String result : results) {
System.out.println(result);
}
}
}
Следующие ссылки могут быть полезны:
- Интерактивная игровая площадка Java, где вы можете экспериментировать и копировать / вставлять код.
- Regex101
- Java RegexTester
- обратные ссылки Java ( необязательная обратная ссылка
\\1
в регулярном выражении). - Ссылка, обобщающая специальные символы Regex, часто встречающиеся в языках
- Ссылка EPub на книгу Java Regex
- Информационный веб-сайт Regex
- Класс сопоставления в документации Javadocs