не совпадать со строкой в ​​скобках регулярное выражение php

Я пытался использовать preg_replace() в php для замены строки. Я хочу сопоставить и заменить все «s» в этой строке, но я только что пришел с решением, только сопоставляющим «s» между «b» и «c» или «s» между > ‹. Есть ли способ использовать отрицательный взгляд не только для символа '>', но и для всей строки? Я не хочу ничего заменять в скобках.

     <text size:3>s<text size:3>absc
     <text size:3>xxetxx<text size:3>sometehing

редактировать: просто введите 's' в> s‹ и в bsc. Затем, когда я изменю строку, например, с «s» на «te», чтобы заменить «te» в xtex и что-то еще. Поэтому я искал регулярное выражение, чтобы ничего не заменять в ‹....>


person mat    schedule 08.03.2016    source источник
comment
Можете ли вы показать строку, которую хотите разобрать, и успешный результат? И, возможно, то, что вы получите взамен. Ваше объяснение на данный момент немного не соответствует действительности.   -  person Yauheni Prakopchyk    schedule 09.03.2016
comment
Вы хотите пропустить <...> вот так?   -  person bobble bubble    schedule 09.03.2016
comment
@Yauheni Prakopchyk Извините, мой вопрос был немного запутанным. Я отредактирую вопрос, но благодаря ответу ниже теперь я это понимаю.   -  person mat    schedule 10.03.2016


Ответы (2)


Вы можете использовать этот шаблон:

$pattern = '/((<[^>]*>)*)([^s]*)s/';
$replace = '\1\3■';                                      # ■ = your replacement string

$result = preg_replace( $pattern, $replace, $str );

демонстрационная версия regex101

Объяснение шаблона:

(               # group 1:
(<[^>]*>)*      # group 2: zero-or-more <...>
)    
([^s]*)         # group 3: zero-or-more not “s”
s               # litterally “s”

Если вы хотите, чтобы совпадение не учитывало регистр, добавьте «i» в конце шаблона:

$pattern = '/((<[^>]*>)*)([^s]*)s/i';

Изменить: объяснение замены

В шаблоне поиска у нас есть 3 группы, окруженные круглыми скобками. В строке замены мы можем ссылаться на группы по синтаксису \1, где 1 — номер группы.

Итак, заменить строку в примере означает: заменить группу 1 на себя, заменить группу 3 на себя, заменить «s» на желаемую замену. Нам не нужно использовать группу 2, потому что она включена в группу 1 (это из-за невозможности регулярного выражения получить повторяющиеся группы).

В демонстрационной строке:

abs<text size:3>ssss<text size:3><img src="img"><text size:3>absc
└┘╵└───────────┘╵╵╵╵└───────────────────────────────────────┘└┘╵╵
└─┘└────────────┘╵╵╵└──────────────────────────────────────────┘
 1  2            345 6

Совпадения с шаблоном:

     group 1    group 3       s
    ---------  ---------  ---------
1 >     0          1          1
2 >     1          0          1
3 >     0          0          1
4 >     0          0          1
5 >     0          0          1    
6 >     3          1          1

Последняя «с» не совпадает, поэтому не заменяется.

person fusion3k    schedule 09.03.2016
comment
Хорошее решение, но я не совсем понимаю его. Таким образом, обе группы записываются перед s в шаблоне, но они также заменяют s, если они появляются после выражения ‹...›. Как это работает? - person Andru; 09.03.2016
comment
Ответ @Andru отредактирован. Дайте мне знать, если это немного яснее. - person fusion3k; 09.03.2016
comment
Ух ты! Ваше дополнительное объяснение многому научило меня в замене с помощью регулярных выражений! Ваша иллюстрация помогла мне понять идею, спасибо! - person Andru; 09.03.2016

Используйте preg_match_all, чтобы получить все s буквы, и используйте его с флагом PREG_OFFSET_CAPTURE, чтобы получить индексы.

Регулярное выражение $pat содержит отрицательный просмотр вперед и назад, поэтому выражение s внутри квадратных скобок не соответствует.

В этом примере я заменяю s строкой 5. Измените строку, которую вы хотите заменить:

<?php

$s = " <text size:3>s<text size:3>absc";
$pat = "/(?<!\<text )s(?!ize:3\>)/";

preg_match_all($pat, $s, $matches, PREG_OFFSET_CAPTURE);

foreach ($matches[0] as $match) {
    $s[$match[1]] = "5";
}

print_r(htmlspecialchars($s));
person Andru    schedule 09.03.2016
comment
ОП: «Я не хочу ничего заменять в скобках» - person fusion3k; 09.03.2016
comment
@ fusion3k Понятно, я пропустил это .. позвольте мне попробовать другое регулярное выражение - person Andru; 09.03.2016
comment
Я предлагаю вам попробовать с этой строкой: sabcs<text size:3>s<text size:3><text size:3>absc ... ;) - person fusion3k; 09.03.2016
comment
Спасибо, а можно ли как-то избежать целой строки в скобках? Например, когда я хочу заменить «t» вместо «s» или что-то еще, чтобы избежать замены строки в скобках? - person mat; 09.03.2016
comment
Обратитесь к шаблону в ответе @ fusion3k. Он делает именно то, что вы хотите, и является более общим, чем мое решение. - person Andru; 09.03.2016