2012-12-11 2 views
1

У меня есть строка, которая является построить так:preg_replace и '|' (OR) не работает в моем регулярном выражении

[propertyname]=[value] 

И propertyname и value могут быть инкапсулированным одинарными или двойными кавычками.

Так я мог бы получить строку, которая выглядит следующим образом:

"height"='max' 

или:

'height'='max' 

Пока оба propertyname и value инкапсулируются того же типа кавычек.

Что мне нужно сделать, это удалить кавычки. Но только вокруг propertyname и value! Поскольку следующее вполне может быть действительной строкой тоже:

"blaat"="Some 'random' blaat" 

Конечный результат должен быть:

blaat=Some 'random' blaat 

У меня есть следующее регулярное выражение, которое работает. Но он работает только тогда, когда я проверяю двойные кавычки или одинарные кавычки. Когда я пытаюсь объединить их с оператором |, он больше не работает.

<?php 
$string = '"height"=\'something "else" in here\''; 

//echo preg_replace ('#"(.*?)"#', '$1', $string); 
//echo preg_replace ('#\'(.*?)\'#', '$1', $string); 
echo preg_replace ('#("(.*?)"|\'(.*?)\')#', '$1', $string); 
?> 

Так что я мог бы просто сделать две preg_replace звонки, но это неприятная работа вокруг рассматривает регулярное выражение должно быть в состоянии справиться с этим в одном вызове ...

Любая идея, что проблема?

+0

Просто используйте символ класс вместо ' '# [' "] [ '# '] (*.?)"'. – Christoph

ответ

4

Ваше регулярное выражение должно соответствовать правильно, но у вас есть проблема: в вашем «комбинированном регулярном выражении» $1 относится ко всему матчу (потому что первый набор круглых скобок охватывает все совпадения), поэтому вы заменяете совпадение с самим собой, включая цитаты.

("(.*?)"|\'(.*?)\') 
^^ ^
|-+--- $1 |---- $3 
    |--- $2 

Теперь вы можете просто удалить внешние скобки:

"(.*?)"|\'(.*?)\' 
^  ^
|--- $1 |---- $2 

Но тогда у вас есть другая проблема: Вы либо должны заменить матч с $1 или $2, в зависимости от того, какая половина из regex соответствовал. Поскольку вы не можете заранее знать, что это будет нелегко. Вы могли бы возможно попробовать и заменить $1$2, но я не знаю, сможет ли PHP разрешить обратную ссылку группе, которая не участвовала в матче.

Лучше перестраховаться и использовать регулярное выражение, которое может обрабатывать оба случая сразу, в том числе сбежавших кавычки внутри строк в кавычках:

$result = preg_replace(
    '/(  # Match and capture (group 1): 
    ["\']  # an opening quote character 
    )   # (End of group 1). 
    (   # Now match and capture (group 2): 
    (?:  # Either... 
     \\\\. # an escaped character 
    |   # or... 
     (?!\1) # (as long as it is not the closing quote) 
     .  # any other character. 
    )*  # Repeat as needed. 
    )   # (End of group 2) 
    \1   # Now match the closing quote./x', 
    '\2', $subject); 
+0

Спасибо большое за большое регулярное выражение :) – Vivendi

1

Либо использовать класс ["'], чтобы захватить как кавычки, или использовать не- захватив группу (?:), чтобы избежать дополнительной группы захвата из-за вмещающую скобку:

'#"(.*?)"#' 
// or 
'#(?:"(.*?)"|\'(.*?)\')#' 
Смежные вопросы