#php #regex #preg-replace
#php #регулярное выражение #preg-replace
Вопрос:
Я пытаюсь удалить разрывы строк и вкладки из содержимого, находящегося внутри скобок, из таких данных:
settings:a [
a:[
a:a
b:b
]
b:[
a:a
b:b
]
]
settings:b [
a:[
a:a
b:b
]
]
Таким образом, становится:
settings:a [ a:[ a:a b:b ] b:[ a:a b:b ] ]
settings:b [ a:[ a:a b:b ] ]
Регулярное выражение, которое я использую n(?=[^[]]*])
, работает в некоторой степени, но я не получаю результат, как указано выше. Вы можете помочь?
Комментарии:
1. хотя это работает с регулярным выражением, вам следует подумать о том, чтобы сделать это с php. Если вы посмотрите на регулярное выражение через несколько месяцев … или хуже — если коллега посмотрит на регулярное выражение через несколько месяцев, он не поймет, что вы там сделали
Ответ №1:
Вы можете использовать следующее регулярное выражение с preg_replace
(таким образом, будет достаточно одного прохода регулярного выражения):
[tn] (?=[^][]*(?:([(?:[^][] |(?1))*])[^][]*)*])
Смотрите демонстрацию регулярных выражений. Подробные сведения:
[tn]
— один или несколько символов табуляции или новой строки (используйтеs
, если вам нужно сопоставить любые пробелы, а также добавьтеu
флаг модификатора, если вам нужно обрабатывать тексты в Юникоде)(?=[^][]*(?:([(?:[^][] |(?1))*])[^][]*)*])
— позитивный прогноз, который требует, чтобы его шаблоны соответствовали сразу справа от текущего местоположения:[^][]*
— ноль или более символов, отличных от[
и]
(?:([(?:[^][] |(?1))*])[^][]*)*
— ноль или более случаев([(?:[^][] |(?1))*])
— Группа 1 (техническая, необходимая для работы рекурсии): a[
, затем любая подстрока между парными вложенными[
и]
, а затем a]
[^][]*
— ноль или более символов, отличных от[
и]
]
—]
символ.
Смотрите демонстрацию PHP:
$re = '/[tn] (?=[^][]*(?:([(?:[^][] |(?1))*])[^][]*)*])/';
$str = "settings:a [n a:[n a:an b:bn ]n b:[n a:an b:bn ]n]nnsettings:b [n a:[n nna:an b:bn ]n]";
echo preg_replace($re, ' ', $str);
// => settings:a [ a:[ a:a b:b ] b:[ a:a b:b ] ]
// settings:b [ a:[ a:a b:b ] ]
Ответ №2:
Вы можете использовать это рекурсивное регулярное выражение в preg_replace_callback
:
$s = 'settings:a [
a:[
a:a
b:b
]
b:[
a:a
b:b
]
]';
echo preg_replace_callback('/[(?:([^][]*)|(?R))*]/', function ($m) {
return preg_replace('/s /', ' ', $m[0]); }, $s) . "n";
Вывод:
settings:a [ a:[ a:a b:b ] b:[ a:a b:b ] ]