Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/235.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Bbcode解析器无法正常工作_Php_Regex_Bbcode - Fatal编程技术网

Php Bbcode解析器无法正常工作

Php Bbcode解析器无法正常工作,php,regex,bbcode,Php,Regex,Bbcode,我的BBCodes有问题-此preg_replace无法正常工作: $message = preg_replace("/\[color=(\#[0-9A-F]{6}|[a-z]+)\](.*)\[\/color\]/Usi", "<span style=\"color:\\1\">\\2</span>", $message); 结果: 但如果有两个颜色标签相继出现,则无法正常工作: [color=#ff0000]text text text text text[/co

我的BBCodes有问题-此
preg_replace
无法正常工作:

$message = preg_replace("/\[color=(\#[0-9A-F]{6}|[a-z]+)\](.*)\[\/color\]/Usi", "<span style=\"color:\\1\">\\2</span>", $message);
结果:

但如果有两个颜色标签相继出现,则无法正常工作:

[color=#ff0000]text text text text text[/color]
[color=#00ffff]texttexttext[/color]
[color=#ff0000][color=#00ffff]text text text text text[/color] [/color]

[color=#ff0000]text text text[color=#00ffff]text text text text text[/color] [/color]
结果:


实际上,在字符串
[color=#ff0000][color=#00ffff]text[/color][/color]
中,正则表达式将第一个打开标记与第一个关闭标记相匹配。避免这种情况的一种方法是稍微修改regexp,例如:

/\[color=(\#[0-9A-F]{6}|[a-z]+)\]([^[]*)\[\/color\]/

然后它将只匹配最嵌套的标记。当字符串包含bbcode时,您需要在循环中执行此操作。

实际上,在字符串
[color=#ff0000][color=#00ffff]text[/color][/color]
中,正则表达式将第一次打开与第一次关闭标记相匹配。避免这种情况的一种方法是稍微修改regexp,例如:

/\[color=(\#[0-9A-F]{6}|[a-z]+)\]([^[]*)\[\/color\]/

然后它将只匹配最嵌套的标记。您需要在循环中执行此操作,而您的字符串包含bbcode。

您也可以通过两个替换来执行此操作。一个用于开头,一个用于结尾标记

那么,这些颜色标签的嵌套就无关紧要了

$message=preg\u replace('%\[color=(\\\\[0-9A-F]{6}\\[a-z]+)\]%i','','',$message);
$message=preg\u replace('%\[/color\]%i',''$message);
或在1个声明中:

$message = preg_replace(
[   '%\[color=(\#[0-9A-F]{6}|[a-z]+)\]%i',
    '%\[/color\]%i'
],
[   '<span style="color:$1">',
    '</span>'
], $message);
$message=preg\u replace(
['%\[color=(\\\[0-9A-F]{6}[a-z]+)\]%i',
“%\[/color\]%i”
],
[   '',
''
],$message);
正如所指出的,不考虑嵌套可能会产生不好的结果

下面是另一个使用while循环和递归正则表达式的方法:

$pattern = '%\[color=(\#[0-9A-F]{6}|[a-z]+)\].*?(((?R)|.)*?)\[\/color\]%i';   
$replacement = '<span style="color:$1">$2</span>';

do {
    $message = preg_replace($pattern, $replacement, $message, -1, $count);
} while ($count);
$pattern='%\[color=(\\[0-9A-F]{6}[a-z]+)\].*(((R)\.*?)\[\/color\]%i';
$replacement='$2';
做{
$message=preg_replace($pattern,$replacement,$message,-1,$count);
}而(计算),;

您也可以通过两次更换来完成。一个用于开头,一个用于结尾标记

那么,这些颜色标签的嵌套就无关紧要了

$message=preg\u replace('%\[color=(\\\\[0-9A-F]{6}\\[a-z]+)\]%i','','',$message);
$message=preg\u replace('%\[/color\]%i',''$message);
或在1个声明中:

$message = preg_replace(
[   '%\[color=(\#[0-9A-F]{6}|[a-z]+)\]%i',
    '%\[/color\]%i'
],
[   '<span style="color:$1">',
    '</span>'
], $message);
$message=preg\u replace(
['%\[color=(\\\[0-9A-F]{6}[a-z]+)\]%i',
“%\[/color\]%i”
],
[   '',
''
],$message);
正如所指出的,不考虑嵌套可能会产生不好的结果

下面是另一个使用while循环和递归正则表达式的方法:

$pattern = '%\[color=(\#[0-9A-F]{6}|[a-z]+)\].*?(((?R)|.)*?)\[\/color\]%i';   
$replacement = '<span style="color:$1">$2</span>';

do {
    $message = preg_replace($pattern, $replacement, $message, -1, $count);
} while ($count);
$pattern='%\[color=(\\[0-9A-F]{6}[a-z]+)\].*(((R)\.*?)\[\/color\]%i';
$replacement='$2';
做{
$message=preg_replace($pattern,$replacement,$message,-1,$count);
}而(计算),;

PHP中现有的BBCode函数怎么样?您看过PHP中现有的BBCode函数了吗?这是一个坏主意,因为如果用户输入格式不正确的bbcode,例如:
[color=#BBCC99]text[/color][/color][/code>所有关闭的
[/color]
标记都会替换为关闭的
标记,从而导致格式不正确的html。预期的行为是不替换不平衡和格式不正确的bbcode标记(这样用户就可以看到并编辑它们)。要解决此问题,可以使用仅描述最内层平衡bbcode标记的模式,在
do…while
循环中,使用
preg\u replace
count
参数停止循环。@casimirithippolyte您是对的。用户可能会把这些标签弄得一团糟。因此,我添加了一个解决方案,考虑到答案中的嵌套。做得好,但描述最里面的bbcode标记比编写递归模式获取最外面的bbcode标记更简单。这是个坏主意,因为如果用户输入格式不正确的bbcode,例如:
[color=#BBCC99]text[/color][/color][/code>全部关闭
[/color]
标记替换为关闭的
标记,导致格式错误的html。预期的行为是不替换不平衡和格式不正确的bbcode标记(这样用户就可以看到并编辑它们)。要解决此问题,可以使用仅描述最内层平衡bbcode标记的模式,在
do…while
循环中,使用
preg\u replace
count
参数停止循环。@casimirithippolyte您是对的。用户可能会把这些标签弄得一团糟。因此,我添加了一个解决方案,该解决方案考虑了答案中的嵌套。做得好,但描述最内层的bbcode标记要比编写递归模式来获取最外层的bbcode标记更简单。您的想法很好。*(匹配最嵌套的标记,并使用循环)*。然而,遗憾的是,只显示模式,而不是您所说的循环的完整php代码。另一方面,使用
[^[]
限制性太强,因为它禁止使用除颜色标签以外的其他标签。但您对原始模式的想法是可行的。如果您想要一个允许其他标签的贪婪模式,您可以将
[^[]*
替换为
[^[]*(?:\[(?!/?color\b)[^[]*)*
。您的模式也有许多反斜杠。为了避免它们,请将分隔符更改为
~
,并在
.
/
]
之前删除反斜杠。添加i修饰符。您的想法很好。*(匹配大多数嵌套标记,并使用循环)*。但是,遗憾的是,只显示模式,而不是您所说的循环的完整php代码。另外,使用
[^[]
限制太多,因为它禁止除颜色标记以外的其他标记。但是您对原始模式的想法是可行的。如果您想要一个允许其他标记的贪婪模式,您可以替换
[^[]*
使用
[^[]*(?:\[(?!/?color\b)[^[]*)*
。您的图案也有许多反斜杠。为避免这些反斜杠,请将分隔符更改为
~
,并在
]
之前删除反斜杠。添加i修饰符。