如何在PmWiki中创建可靠的多行自定义标记?
在PmWiki里创建可靠的多行自定义标记,核心是搞定正则表达式的多行匹配逻辑,以及正确设置标记的解析优先级——这也是很多人测试有效但实际场景翻车的常见原因。我来给你拆解正确的实现方式和避坑点:
1. 核心实现:用Markup()注册多行标记
PmWiki的自定义标记都通过Markup()函数注册,重点是正则表达式要能覆盖多行内容,同时避免匹配溢出。
举个最常用的例子:假设你想做一个[[myblock]]...[[/myblock]]的块标记,把内容包裹成带自定义类的<div>,正确的代码应该是这样的:
// 放在local/config.php或者自定义插件文件里 Markup('myblock', 'directives', '/\\[\\[myblock\\]\\](.*?)\\[\\[\\/myblock\\]\\]/s', '<div class="my-block">$1</div>' );
这里的关键细节:
/s修饰符:让正则里的.能匹配换行符,这是多行匹配的核心,没有它的话只能匹配单行内容.*?非贪婪匹配:确保只匹配到最近的[[/myblock]],而不是页面最后一个,避免把中间其他内容也包进去- 优先级设为
directives:这个优先级比较高,会在PmWiki处理段落、列表等标记前先解析你的块,避免标记被拆碎
如果你的服务器环境对s修饰符支持有问题,可以用[\s\S]*?替代.*?,效果是一样的(匹配所有空白+非空白字符,也就是所有内容包括换行):
Markup('myblock', 'directives', '/\\[\\[myblock\\]\\]([\\s\\S]*?)\\[\\[\\/myblock\\]\\]/', '<div class="my-block">$1</div>' );
2. 解决实际场景失效的常见坑
你说基础测试有效但实际用不了,大概率是踩了这几个坑:
- 没处理多行匹配:正则没加
s修饰符,也没用[\s\S],导致只能匹配单行内容,跨越多行就失效 - 贪婪匹配导致溢出:用了
.*而不是.*?,会把从第一个[[myblock]]到页面最后一个[[/myblock]]之间的所有内容都匹配进去,破坏结构 - 优先级设置错误:如果优先级设得太低(比如比
block还低),PmWiki会先把你的标记内容拆成段落、列表,导致标记被打散,无法正确匹配 - 标记语法冲突:如果你的开始/结束标记和PmWiki原生标记太像(比如用了
(:xxx:这种格式却没避开原生指令),会被原生解析器先处理掉
3. 进阶:让块内内容支持PmWiki原生标记
如果希望你的多行块里面还能正常解析链接、列表等PmWiki标记,只需要把优先级调低,比如设为postblock(在原生块标记解析之后运行):
Markup('myblock', 'postblock', '/\\[\\[myblock\\]\\]([\\s\\S]*?)\\[\\[\\/myblock\\]\\]/', '<div class="my-block">$1</div>' );
这样PmWiki会先解析块内的所有原生标记,再把结果包裹到你的<div>里。
4. 另一种常见语法:指令式标记
很多人喜欢用(:myblock:)和(:myblockend:)这种指令风格的标记,实现方式类似:
Markup('myblock', 'directives', '/\\(:myblock:\\)([\\s\\S]*?)\\(:myblockend:\\)/', '<div class="my-block">$1</div>' );
这种语法和PmWiki原生指令风格统一,不容易和其他标记冲突。
内容的提问来源于stack exchange,提问作者wizzwizz4
相关产品推荐
相关产品推荐

