RegExp-задачка

Столкнулся с такой задачей: есть строка, в которой произвольные куски текста могут содержаться в скобках. Нужно выбрать все четырёхзначные числа (год́а), которые вне скобок.
Например, из строки:
$text = "(P. 1: 15. X. 1481; P. 2: 4. XII. 1482); P. 3: 18. II. 1483;
 P. 4: 10. VI. 1484; P. 5: 10. VI. 1485; (P. 6: 6. IX. 1486; P. 7: 17. VII. 1487);
 P. 8: 17. VII. 1480";

нужно выбрать значения 1483, 1484, 1485, 1480.

Убил уйму времени, пытаясь решить это одним RegExp'ом — никак.
Пришлось разбить на два этапа:
$pattern = "/\(.*\)/U";
$r = preg_replace($pattern, '', $text);
$pattern = "/\d{4}/";
preg_match_all($pattern, $r, $matches);
print_r($matches[0]);

Можно ли было обойтись одним выражением?
  • Вопрос задан
  • 3052 просмотра
Решения вопроса 1
Wott
@Wott
Правильно послал вас к позиционным проверкам

Смысл в том что бы исключить условие что цифры внутри скобок, то есть вводим проверку на отсутствие впереди закрывающей скобки (?!.*\)). Но возникнет проблема в том что мы можем таким образом захватить пару скобок впереди. Для исключения этого случая вместо любого символа ищем все, кроме открывающей скобки, — (?![^\(]*\))

Конечный регэксп выглядит так: /\d{4}(?![^\(]*\))/
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы