- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在编写一个简单的 Javascript,以将特定参数添加到当前正在编辑的文章中的特定模板。
维基百科模板的结构如下:
{{Template name|unnamed parameter|named parameter=some value|another parameter=[[target article|article name]]|parameter={{another template|another tamplate's parameter}}}}
一个模板也可以覆盖多行,例如:
{{Template
|name=John
|surname=Smith
|pob=[[London|London, UK]]
}}
如需进一步引用,请查看 http://en.wikipedia.org/wiki/Help:Template
所以首先我想匹配整个模板。我过来了部分解决方案,即:
document.editform.wpTextbox1.value.match(/\{\{template name((.|\n)*?)\}\}$/gmis)
但是问题是它只匹配从初始括号到第一个嵌套模板(第一个示例)的右括号的文本。
另外我想以数组形式获取它的参数。因此,对于结果,我想获得一个包含特定顺序参数的数组。 Array( 参数 pob 的值,参数 name 的值,参数 surname 的值,参数 pod 的值(在本例中为空,因为它未设置))
我会用它来清理某些文章中的非标准化格式并添加一些新参数。
谢谢!
最佳答案
编写简单的解析器。
用正则表达式解决这类问题是不对的。它与匹配括号相同 - 很难用正则表达式来做。正则表达式一般不适用于嵌套表达式。
尝试这样的事情:
var parts = src.split(/(\{\{|\}\})/);
for (var i in parts) {
if (parts[i] == '{{') // starting new (sub) template
else if (parts[i] == '}}') // ending (sub) template
else // content (or outside)
}
这只是伪代码,因为我现在很着急,将更新此代码以使其正常工作...
更新(2011 年 8 月 9 日)
var NO_TPL = 0, // outside any tpl - ignoring...
IN_TPL = 1, // inside tpl
IN_LIST = 3; // inside list of arguments
function parseWiki(src) {
var tokens = src.split(/(\{\{|\}\}|\||=|\[\[|\]\])/),
i = -1, end = tokens.length - 1,
token, next, state = NO_TPL,
work = [], workChain = [], stateChain = [];
function trim(value) {
return value.replace(/^\s*/, '').replace(/\s*$/, '');
}
// get next non empty token
function getNext(next) {
while (!next && i < end) next = trim(tokens[++i]);
return next;
}
// go into tpl / list of arguments
function goDown(newState, newWork, newWorkKey) {
stateChain.push(state);
workChain.push(work);
if (newWorkKey) {
work[newWorkKey] = newWork;
} else {
work.push(newWork);
}
work = newWork;
state = newState;
}
// jump up from tpl / list of arguments
function goUp() {
work = workChain.pop();
state = stateChain.pop();
}
// state machine
while ((token = getNext())) {
switch(state) {
case IN_TPL:
switch(token) {
case '}}': goUp(); break;
case '|': break;
default:
next = getNext();
if (next != '=') throw "invalid";
next = getNext();
if (next == '[[') {
goDown(IN_LIST, [], token);
} else if (next == '{{') {
goDown(IN_TPL, {id: getNext()}, token);
} else {
work[token] = next;
}
}
break;
case IN_LIST:
switch(token) {
case ']]': goUp(); break;
case '|': break;
default: work.push(token);
}
break;
case NO_TPL:
if (token == '{{') {
next = getNext();
goDown(IN_TPL, {id: next});
}
break;
}
}
return work;
}
单元测试
describe('wikiTpl', function() {
it('should do empty tpl', function() {
expect(parseWiki('{{name}}'))
.toEqual([{id: 'name'}]);
});
it('should ignore text outside from tpl', function() {
expect(parseWiki(' abc {{name}} x y'))
.toEqual([{id: 'name'}]);
});
it('should do simple param', function() {
expect(parseWiki('{{tpl | p1= 2}}'))
.toEqual([{id: 'tpl', p1: '2'}]);
});
it('should do list of arguments', function() {
expect(parseWiki('{{name | a= [[1|two]]}}'))
.toEqual([{id: 'name', a: ['1', 'two']}]);
});
it('should do param after list', function() {
expect(parseWiki('{{name | a= [[1|two|3]] | p2= true}}'))
.toEqual([{id: 'name', a: ['1', 'two', '3'], p2: 'true'}]);
});
it('should do more tpls', function() {
expect(parseWiki('{{first | a= [[1|two|3]] }} odd test {{second | b= 2}}'))
.toEqual([{id: 'first', a: ['1', 'two', '3']}, {id: 'second', b: '2'}]);
});
it('should allow nested tpl', function() {
expect(parseWiki('{{name | a= {{nested | p1= 1}} }}'))
.toEqual([{id: 'name', a: {id: 'nested', p1: '1'}}]);
});
});
注意:我在这些单元测试中使用了 Jasmine 的语法。您可以使用包含整个测试环境的 AngularJS 轻松运行它 - 在 http://angularjs.org 查看它
关于javascript - 用于匹配 MediaWiki 模板及其参数的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6532276/
我有很多文本文件要上传到运行 MediaWiki 的 wiki。 我什至不知道这是否真的可能,但我想试一试。 每个文本文件的名称将是 wiki 页面的标题。 一个 wiki 页面对应一个文件。 我想从
是否可以使用 SyntaxHighlight GeSHi 在 MediaWiki 中缩进一段代码? ? 比如我希望下面的代码容器与三级列表对齐 * This is plain text of a fi
是否可以在 MediaWiki 中定义可缩进和可折叠的文本或代码块(例如,使用语法高亮格氏格式化)? 我在 Wikipedia 中看到了可折叠的表格和列表,并希望将相同的概念应用于段落和代码片段。 谢
mediawiki 数据库中的哪个表保存页面内容?我想直接访问 mediawiki 的数据库。 最佳答案 您可以查看database layout媒体维基。页面内容位于表格text (在 Postgr
在 MediaWiki 中,您可以使用变量(“Magic Word”),例如 {{PAGENAME}} 或 {{REVISIONDAY}} 获取与当前正在查看的页面相关的特定信息。是否有类似的变量(或
我正在尝试在 wiki 页面上放置一个对象列表,供多个团队标记他们使用的对象。为此,我为每个团队制作了一个带有一列的表格,并希望在这些列中放置一个复选框,以便团队进行标记。 这是我要做的事情的基本思想
有没有MediaWIki我可以在其中提交整个(可能非常大)mediawiki 文本(用于维基百科文章)的 API,这将给我提供与在 wikipedia 上查看的 HTML 文章完全相同的 HTML对于
有没有MediaWIki我可以在其中提交整个(可能非常大)mediawiki 文本(用于维基百科文章)的 API,这将给我提供与在 wikipedia 上查看的 HTML 文章完全相同的 HTML对于
我正在寻找一种方法来防止所有用户在 Mediawiki 中更改他们的密码(因为帐户创建和密码更改由中央 SSO 服务器处理)。 据我所知,Mediawiki 用户可以通过两种方式更改密码:使用登录页面
背景: 我与一个大型协作机构合作,该机构将大量文档集中在一个 wiki 结构中。我已经熟悉 wiki 标记,并且可以创建带有链接等的简单页面。 我合作的 wiki(基于 mediawiki 架构)的一
我正在运行一个 MediaWiki 实例,在撰写本文时我刚刚将其升级到最新版本 1.32.0。这个 wiki 已有近 10 年的历史,并且经历了多次升级。 这是一个法语维基,对于说法语的人来说,令人讨
通过访问 sysop 和数据库访问,我如何更改与用户关联的电子邮件地址? 数据库中的用户表将所有内容都编码为 BLOB。如果我可以解码和编码这些值,大概我可以更新 user.user_email。 最
MediaWiki 支持的侧边栏的默认左侧边栏包含诸如“随机页面”和“当前事件”之类的链接。我想隐藏这些。 除了使用 CSS ( display:none; ) 之外,还有其他方法可以做到这一点吗?
如何设置才能让 MediaWiki 不允许一个电子邮件地址创建多个帐户?垃圾邮件机器人仅使用一封电子邮件创建了 5 个帐户。 我一直在寻找配置设置或扩展,但没能找到。 与此相关的一个问题是使用类似于
我有一个包含不同类型类别的 mediawiki。 如果一个页面有 2 个类别 [[Category:Pear]][[Category:Strawberry]]) 我想添加第三个类别 [[Categor
我们的网络上有自定义协议(protocol),可以在我们的应用程序中打开窗口。我们想在我们的 Wiki 中放置此应用程序的链接,但 mediawiki 似乎唯一识别的协议(protocol)是 htt
我想在 mediawiki 中找到图像的确切 URL 以发送到我的 pinterest 代码中。要查找页面 URL,我使用 urlencode($wgTitle->getFullURL()) 但我无法
我不太确定这在 MediaWiki 中是否可行。 我有几个类别,每个类别包含几页。如果您打开一个类别页面,您将看到该类别的内容,通常由以下三个部分组成: 用户定义的文本(可以使用编辑链接进行编辑)。
我开发了一个应用程序,它在 mediawiki 站点上有一个手册/帮助系统。当用户在应用程序中需要帮助时,他/她可以点击一个按钮,访问维基上相应的帮助页面。这工作得很好,当我在应用程序中添加/更改功能
我刚刚安装了 Mediawiki 并意识到为新手配置它非常复杂。 作为我的第一个条目,我想更改字体颜色: {{ font color | green | green text }} 为此,我从 Wik
我是一名优秀的程序员,十分优秀!