Вопрос о регулярных выражениях Java

#java #regex

#java #регулярное выражение

Вопрос:

У меня есть текст, что-то вроде

 ab1ab2ab3ab4cd
  

Можно ли создать регулярное выражение Java для получения всех подстроков, которые начинаются с "ab" и заканчиваются на "cd" ? например:

 ab1ab2ab3ab4cd
ab2ab3ab4cd
ab3ab4cd
ab4cd
  

Спасибо

Ответ №1:

Регулярное выражение (?=(ab.*cd)) сгруппирует такие совпадения в группу 1, как вы можете видеть:

 import java.util.regex.*;

public class Main {
  public static void main(String[] args) throws Exception {

    Matcher m = Pattern.compile("(?=(ab.*cd))").matcher("ab1ab2ab3ab4cd");

    while (m.find()) {
      System.out.println(m.group(1));
    }
  }
}
  

который выдает:

 ab1ab2ab3ab4cd
ab2ab3ab4cd
ab3ab4cd
ab4cd
  

Вам нужно смотреть вперед, (?= ... ) иначе вы получите только одно совпадение. Обратите внимание, что регулярное выражение не даст желаемых результатов, если в вашей строке больше 2 cd ‘s. В этом случае вам придется прибегнуть к некоторому ручному строковому алгоритму.

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

1. Для моего любопытства, для «перевернутого» случая, как должен выглядеть rx? Строка — ab1cd2cd3cd, и я хочу ab1cd, ab1cd2cd, ab1cd2cd3cd

2. @Dudu, вы не можете сделать это с помощью регулярных выражений: механизм регулярных выражений вычисляет слева направо.

Ответ №2:

Похоже, вы хотите либо abw ?cd , либо babw ?cdb

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

1. Я подозреваю, что второе больше соответствует тому, что он хочет, или более реалистично тому, что ему нужно.

2. Итак, как вы получите все подстроки, соответствующие этому шаблону?

3. Нет, это позволит найти только одну подстроку.

4. Извините, неправильно истолковал вопрос. Вы все равно могли бы найти все подстроки, повторно вызывая find со смещением сразу за началом последнего совпадения, но решение Bart более чистое.

Ответ №3:

 /^ab[a-z0-9] cd$/gm
  

Если только a b c и digits 0-9 могут появляться в середине, как в примерах:

 /^ab[a-cd] cd$/gm
  

Посмотрите на это в действии: http://regexr.com ?2tpdu

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

1. Это будет просто сопоставлять / проверять одну строку, но OP спросил, есть ли регулярное выражение, которое соответствует всем (под) строкам, которые соответствуют определенному шаблону.

2. @Bart Я незнаком с Java, есть ли у нее глобальный и многострочный модификатор?

3. Нет, глобального модификатора нет. Вам придется самостоятельно просмотреть все возможные соответствия, и как только (вспомогательный) шаблон будет сопоставлен, он не может быть частью другого соответствия: вот почему я использовал прогноз нулевой ширины в своем ответе.