Php 解析类似Wordpress的短代码
我想用属性解析像Wordpress这样的短代码: 输入:Php 解析类似Wordpress的短代码,php,Php,我想用属性解析像Wordpress这样的短代码: 输入: [include file="header.html"] 我需要作为数组输出,函数名“包括”和属性值以及,任何帮助将不胜感激 感谢使用 $command将为“include” $attribute将为“文件” $attributeValue将是“header.html”这实际上比表面上看起来更难。Andrew的答案是可行的,但如果源文本中出现方括号(例如,像这样),答案就开始失效。WordPress的工作原理是预先注册一个有效短代码列表
[include file="header.html"]
我需要作为数组输出,函数名“包括”和属性值以及,任何帮助将不胜感激
感谢使用
$command将为“include”
$attribute将为“文件”
$attributeValue将是“header.html”这实际上比表面上看起来更难。Andrew的答案是可行的,但如果源文本中出现方括号(例如,像这样),答案就开始失效。WordPress的工作原理是预先注册一个有效短代码列表,并且仅在括号内的文本与这些预定义值之一匹配时才对其进行操作。这样,它就不会破坏任何可能恰好有一组方括号的常规文本 WordPress shortcode引擎的实际功能相当强大,修改文件以使其自行运行看起来并不困难——然后您可以在应用程序中使用它来处理困难的工作。(如果您感兴趣,请查看该文件中的
get\u shortcode\u regex()
,看看这个问题的正确解决方案实际上有多复杂。)
使用WP shortcodes.php对您的问题进行一次非常粗略的实现,看起来像是:
// Define the shortcode
function inlude_shortcode_func($attrs) {
$data = shortcode_atts(array(
'file' => 'default'
), $attrs);
return "Including File: {$data['file']}";
}
add_shortcode('include', 'inlude_shortcode_func');
// And then run your page content through the filter
echo do_shortcode('This is a document with [include file="header.html"] included!');
再说一次,根本没有经过测试,但它不是一个很难使用的API。我的PHP框架中也需要这个功能。这是我写的,效果很好。它使用匿名函数,我非常喜欢(有点像JavaScript中的回调函数)
结果:你好,我叫约翰,今年22岁。
你好,我叫卡罗尔·安,今年17岁。这是我们在项目中使用的实用程序类 它将匹配字符串中的所有短代码(包括html),并将输出一个关联数组,包括它们的
名称
、属性
和内容
final class Parser {
// Regex101 reference: https://regex101.com/r/pJ7lO1
const SHORTOCODE_REGEXP = "/(?P<shortcode>(?:(?:\\s?\\[))(?P<name>[\\w\\-]{3,})(?:\\s(?P<attrs>[\\w\\d,\\s=\\\"\\'\\-\\+\\#\\%\\!\\~\\`\\&\\.\\s\\:\\/\\?\\|]+))?(?:\\])(?:(?P<content>[\\w\\d\\,\\!\\@\\#\\$\\%\\^\\&\\*\\(\\\\)\\s\\=\\\"\\'\\-\\+\\&\\.\\s\\:\\/\\?\\|\\<\\>]+)(?:\\[\\/[\\w\\-\\_]+\\]))?)/u";
// Regex101 reference: https://regex101.com/r/sZ7wP0
const ATTRIBUTE_REGEXP = "/(?<name>\\S+)=[\"']?(?P<value>(?:.(?![\"']?\\s+(?:\\S+)=|[>\"']))+.)[\"']?/u";
public static function parse_shortcodes($text) {
preg_match_all(self::SHORTOCODE_REGEXP, $text, $matches, PREG_SET_ORDER);
$shortcodes = array();
foreach ($matches as $i => $value) {
$shortcodes[$i]['shortcode'] = $value['shortcode'];
$shortcodes[$i]['name'] = $value['name'];
if (isset($value['attrs'])) {
$attrs = self::parse_attrs($value['attrs']);
$shortcodes[$i]['attrs'] = $attrs;
}
if (isset($value['content'])) {
$shortcodes[$i]['content'] = $value['content'];
}
}
return $shortcodes;
}
private static function parse_attrs($attrs) {
preg_match_all(self::ATTRIBUTE_REGEXP, $attrs, $matches, PREG_SET_ORDER);
$attributes = array();
foreach ($matches as $i => $value) {
$key = $value['name'];
$attributes[$i][$key] = $value['value'];
}
return $attributes;
}
}
print_r(Parser::parse_shortcodes('[include file="header.html"]'));
更新@Duco的代码片段,就像它看起来一样,它被空间爆炸了,当我们有一些类似的东西时,这些空间就会被破坏
[Image source="myimage.jpg" alt="My Image"]
至当前版本:
function handleShortcodes($content, $shortcodes){
function read_attr($attr) {
$atList = [];
if (preg_match_all('/\s*(?:([a-z0-9-]+)\s*=\s*"([^"]*)")|(?:\s+([a-z0-9-]+)(?=\s*|>|\s+[a..z0-9]+))/i', $attr, $m)) {
for ($i = 0; $i < count($m[0]); $i++) {
if ($m[3][$i])
$atList[$m[3][$i]] = null;
else
$atList[$m[1][$i]] = $m[2][$i];
}
}
return $atList;
}
//Loop through all shortcodes
foreach($shortcodes as $key => $function){
$dat = array();
preg_match_all("/\[".$key."(.*?)\]/", $content, $dat);
if(count($dat) > 0 && $dat[0] != array() && isset($dat[1])){
$i = 0;
$actual_string = $dat[0];
foreach($dat[1] as $temp){
$params = read_attr($temp);
$content = str_replace($actual_string[$i], $function($params), $content);
$i++;
}
}
}
return $content;
}
$content = '[image source="one" alt="one two"]';
更新(2020年2月11日)它似乎在preg_match下的regex后面,只标识带有属性的短代码
preg_match_all("/\[".$key." (.+?)\]/", $content, $dat);
使其正常使用[contact form]或[mynotes]。我们可以将以下内容更改为
preg_match_all("/\[".$key."(.*?)\]/", $content, $dat);
我用wordpress函数修改了上述函数
function extractThis($short_code_string) {
$shortocode_regexp = "/(?P<shortcode>(?:(?:\\s?\\[))(?P<name>[\\w\\-]{3,})(?:\\s(?P<attrs>[\\w\\d,\\s=\\\"\\'\\-\\+\\#\\%\\!\\~\\`\\&\\.\\s\\:\\/\\?\\|]+))?(?:\\])(?:(?P<content>[\\w\\d\\,\\!\\@\\#\\$\\%\\^\\&\\*\\(\\\\)\\s\\=\\\"\\'\\-\\+\\&\\.\\s\\:\\/\\?\\|\\<\\>]+)(?:\\[\\/[\\w\\-\\_]+\\]))?)/u";
preg_match_all($shortocode_regexp, $short_code_string, $matches, PREG_SET_ORDER);
$shortcodes = array();
foreach ($matches as $i => $value) {
$shortcodes[$i]['shortcode'] = $value['shortcode'];
$shortcodes[$i]['name'] = $value['name'];
if (isset($value['attrs'])) {
$attrs = shortcode_parse_atts($value['attrs']);
$shortcodes[$i]['attrs'] = $attrs;
}
if (isset($value['content'])) {
$shortcodes[$i]['content'] = $value['content'];
}
}
return $shortcodes;
}
函数提取此($short\u code\u string){
(3)P(P)[\\w\\-[3,,,)3,,,,)3,,,,,,,,,,,,,,,,::::::::::::::::::::::::::::::::::::::::::::::::::::::::,,,,\\\\\\\\\\\\..0 0 0.0 0.0 0.0.0.0,,,,\\\\\\\\\\\\\\\\\\\\\\\\\\\\农村农村农村农村农村农村农村农村农村农村农村地区的,,,,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\s\\\/\\?\\\\\\\]+(?:\\[\\/[\\w\\-\\\\\\\\\\]+\])))?)/u”;
preg_match_all($shortocode_regexp,$short_code_string,$matches,preg_SET_ORDER);
$shortcodes=array();
foreach($匹配为$i=>$value){
$shortcode[$i]['shortcode']=$value['shortcode'];
$shortcode[$i]['name']=$value['name'];
如果(isset($value['attrs'])){
$attrs=shortcode_parse_atts($value['attrs']);
$shortcode[$i]['attrs']=$attrs;
}
如果(isset($value['content'])){
$shortcode[$i]['content']=$value['content'];
}
}
返回$shortcode;
}
我认为这对所有人都有帮助:)我可以看到错误:致命错误:调用wp_parse.php中未定义的函数GetBetween(),在第4行阅读我答案的第一行,你需要将这段代码粘贴到你的文件:
函数GetBetween($content,$start,$end){$r=explode($start,$content);if(isset($r[1]){$r=explode($end,$r)[1] );返回$r[0];}返回“”;}
@ShahzabAsif我没有测试我的代码,所以请告诉我它是否适合您。请尝试我的库,它是独立的,并且已经在生产中经过了战斗测试:。如果您需要什么,请告诉我!@TomaszKowalczyk谢谢!:)这很好。但是有没有办法替代它。它只是转换短代码,并删除所有其他需要的文本问题要求它解析短代码并将其作为关联数组输出。然后,你可以获取每个元素并生成你喜欢的任何输出。你可以做类似于str\u replace($shortcode,$compiled\u shortcode,$string)的事情
将搜索短代码,并将其替换为在字符串中生成的$compiled\u output
。通常字符串是整个html,就像post\u内容一样
在值只有1个字符长(例如id=8或id=“8”)时不幸无法工作。我想我已经修复了它:如果您包含一个工作示例,那会更好。这段代码很棒-谢谢!我注意到如果您将explode更改为$temp=explode(“”,$temp);那么您可以在引用的值中使用空格。
array(
[source] => myimage.jpg,
[alt] => My Image
)
preg_match_all("/\[".$key." (.+?)\]/", $content, $dat);
preg_match_all("/\[".$key."(.*?)\]/", $content, $dat);
function extractThis($short_code_string) {
$shortocode_regexp = "/(?P<shortcode>(?:(?:\\s?\\[))(?P<name>[\\w\\-]{3,})(?:\\s(?P<attrs>[\\w\\d,\\s=\\\"\\'\\-\\+\\#\\%\\!\\~\\`\\&\\.\\s\\:\\/\\?\\|]+))?(?:\\])(?:(?P<content>[\\w\\d\\,\\!\\@\\#\\$\\%\\^\\&\\*\\(\\\\)\\s\\=\\\"\\'\\-\\+\\&\\.\\s\\:\\/\\?\\|\\<\\>]+)(?:\\[\\/[\\w\\-\\_]+\\]))?)/u";
preg_match_all($shortocode_regexp, $short_code_string, $matches, PREG_SET_ORDER);
$shortcodes = array();
foreach ($matches as $i => $value) {
$shortcodes[$i]['shortcode'] = $value['shortcode'];
$shortcodes[$i]['name'] = $value['name'];
if (isset($value['attrs'])) {
$attrs = shortcode_parse_atts($value['attrs']);
$shortcodes[$i]['attrs'] = $attrs;
}
if (isset($value['content'])) {
$shortcodes[$i]['content'] = $value['content'];
}
}
return $shortcodes;
}