我试图只替换两个符号之间的字符串,并在字符串包含特定字时开始替换,例如:
$string = '%Test% %font-style:italic; font-weight:bold;%'; //It Can be with different orders such as $string = '%Test% %font-weight:bold; font-style:italic;%';
所以我想要使用preg_replace for的字符串是这两个符号%%
之间的字符串,我想使用preg_replace,如果字符串包含一个css标签,例如font-style:italic; color:red; font-weight:bold; etc..
I&#39我试过了
$string = preg_replace('`\%(.*?)((.*?):(.*?);)(.*?)\%`si', '(span style="$2$5")', $string); // ( used as start tag html symbol
但是当我用它
时它引起了一个问题http://localhost/NaiTreNo/Games/Games/BatMan%20Arkham%20Knight/Image/Cover.jpg :D %color:blue; font-weight:bold;%
它应该返回:
http://localhost/NaiTreNo/Games/Games/BatMan%20Arkham%20Knight/Image/Cover.jpg :D
<span style="color:blue; font-weight:bold;">
但它回来了:
http://localhost/NaiTreNo/Games/Games/BatMan<span style="20Arkham%20Knight/Image/Cover.jpg :D %color:blue; font-weight:bold;%">
请帮忙。
答案 0 :(得分:3)
regex
太宽松了。它只检查字符串中某处:
和;
的存在。我会使用CSS属性名称具有特定格式的知识来制定regex
规则,该规则不会匹配包含:
和;
的任何字符串。
例如,像这样:
#%(([a-z]+(-[a-z]+){0,2}: *[^;]+;)+)(.*?)%#si
CSS
property name以包含一个或多个小写字母[a-z]+
的单词开头,后跟零,一个或两个以上的单词,每个单词前面都有一个短划线(-[a-z]+){0,2}
。
也可以创建限制用于值的过于接受的.*?
的规则,但结果不会付出努力(并且regex
变得难以理解。
regex
如何运作:
% # your custom boundary start symbol
( # start of group #1 used to capture the CSS rules
( # start of group #2 that captures a single CSS rul
[a-z]+ # first word of CSS property name
(-[a-z]+){0,2} # 0-2 more words, separated with dash (-)
: * # the colon followed by optional white spaces
[^;]+; # anything until the first semicolon (at least one character)
)+ # end of group #2; it can repeat; at least one occurence is required
) # end of group #1
(.*?) # captures everything after the last semicolon
% # your custom boundary end symbol
当只有一个CSS属性并且其值后面没有分号(f.e)时,上面的regex
不匹配。 %color: red%
。为了解决这个问题,第2组之后的+
符号必须替换为*
(以匹配零个或多个以;
结尾的CSS规则)但这样结束{{1将匹配任何内容,包括(.*?)
或示例中的网址。
可以通过将最后一组中的Test
替换为组#2的内容而不使用结尾.*?
来解决此问题。表达变得更长,更难以理解,我不会在这里发布。最好确保CSS规则始终以分号(;
)结尾,包括最后一个分号。
可以在https://regex101.com/r/vC1oS2/3
找到此;
的游乐场
答案 1 :(得分:0)