2016-03-08 5 views
1

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

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

редактировать: просто получить 'S' в> ы < и в Бакалавра. Затем, когда я буду менять строку, например, с 's' на 'te', чтобы заменить 'te' в xtex и sometehing. Так что я искал регулярное выражение, чтобы избежать замены ничего в < ....>

+0

Можете ли вы показать строку, которую хотите разбить и добиться результата? И, вероятно, вы получите вместо этого. Ваше объяснение на данный момент немного не работает. –

+0

Вы хотите [пропустить '<'...'>' как это?] (Https://regex101.com/r/zD9iJ0/1) –

+0

@Yauheni Prakopchyk Извините, мой вопрос был немного запутанным.Я отредактирую вопрос, но, спасибо ниже, я понимаю это сейчас. – mat

ответ

2

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

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

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

regex101 demo

Узор объяснение:

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

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

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

Edit: Замена объяснение

В шаблоне поиска мы имеем 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 

Pattern матчей:

 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 

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

+0

Хорошее решение, но я не совсем понимаю его. Таким образом, обе группы записываются до 's' в шаблоне, но также заменяют' s', если оно появляется после выражения <...>. Как это работает? – Andru

+0

@Andru ответить отредактирован. Дайте мне знать, если это будет немного яснее. – fusion3k

+0

Ничего себе! Ваше дополнительное объяснение научило меня много о замене регулярными выражениями! Ваша иллюстрация помогла мне получить эту идею, спасибо! – Andru

0

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

Регулярное выражение $pat содержит отрицательный lookahead и lookbehind, так что выражение 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)); 
+0

OP: «Я не хочу ничего заменять в скобках» – fusion3k

+0

@ fusion3k Я вижу, я пропустил это. Позвольте мне попробовать другое регулярное выражение. – Andru

+1

Я предлагаю вам попробовать с этой строкой: 'sabcs s absc'. ..;) – fusion3k