提问者:小点点

preg_replace只替换两个符号之间的字符串,如果它包含特定的内容


我尝试只替换两个符号之间的字符串,并在字符串包含特定单词时开始替换,例如:

$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的字符串是这两个符号之间的字符串%%,我想要使用preg_replace,只要字符串包含一个css标记,例如字体样式:italic;颜色:红色;字体大小:粗体;等等

$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;%">

请帮忙。


共2个答案

匿名用户

你的regex太松了。它只检查字符串中某处是否存在。我将使用CSS属性名称具有特定格式的知识来创建一个regex规则,该规则不匹配包含的任何字符串。

例如,类似这样的内容:

#%(([a-z]+(-[a-z]+){0,2}: *[^;]+;)+)(.*?)%#si

CSS属性名以包含一个或多个小写字母[a-z]的单词开头,后面是零,一个或两个以上的单词,每个单词前面都有破折号(-[a-z]){0,2}

限制太接受的规则。*?也可以创建用于值的,但结果不会付出代价(并且正则表达式变得难以理解。

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属性且其值后面没有分号时,上面的regex不匹配,例如%color:red%。为了解决此问题,必须将组2后面的符号替换为*(以匹配零个或多个以结尾的CSS规则),但这样结尾的(*)将匹配任何内容,包括Test或示例中的URL。

可以通过替换*在最后一组中,内容为第2组,无结尾。这个表达变得越来越长,越来越难理解,我不会在这里发布。您最好确保CSS规则始终以分号()结尾,包括最后一个分号。

regex的游乐场位于:https://regex101.com/r/vC1oS2/3

匿名用户

我可以建议在开头加一个空格。

$string = preg_replace('`(^| )\%(.*?)((.*?):(.*?);)(.*?)\%`si', ' <span style="$2$5">', $string); // ( used as start tag html symbol

试试https://3v4l.org/uubF7