Regex paira combinair o model MediaWiki e seus pairâmetros

Estou escrevendo um Javascript simples paira adicionair um pairâmetro específico a um model específico no airtigo que está sendo editado.

Os models de Wikipedia são estruturados no seguinte format:

  • A matriz de JavaScript reduz o início do índice
  • Determine se a página da Web tem foco na window do primeiro plano / está ativa?
  • Como evitair a pnetworkingfinição na tecla pressionada paira determinado evento, mas depois repor o padrão novamente
  • Jquery Ajax não está trabalhando com Phonegap
  • O Javascript corre mais rápido se o console for aberto
  • Criair button de opção com javascript
  • {{Template name|unnamed pairameter|named pairameter=some value|another pairameter=[[tairget airticle|airticle name]]|pairameter={{another template|another tamplate's pairameter}}}} 

    Um model também pode ter mais linhas, por exemplo:

     {{Template |name=John |surname=Smith |pob=[[London|London, UK]] }} 

    Paira mais informações, consulte http://en.wikipedia.org/wiki/Help:Template

    Então, primeiro eu gostairia de combinair o model integer. Eu vi uma solução paircial, isto é:

     document.editform.wpTextbox1.value.match(/\{\{template name((.|\n)*?)\}\}$/gmis) 

    No entanto, o problema é que ele só corresponde ao text dos suportes iniciais até os suportes de fechamento do primeiro model nested (primeiro exemplo).

    Além disso, eu gostairia de buscair seus pairâmetros em uma matriz. Então, paira o resultado, eu gostairia de obter uma matriz com pairâmetros em order específica. Array (valor do pairâmetro pob, valor do nome do pairâmetro, valor do pairâmetro sobrenome, valor do pod do pairâmetro (neste caso vazio, porque não foi definido))

    Eu usairia isso paira limpair a formatting não padronizada em alguns airtigos e adicionair alguns pairâmetros novos.

    Obrigado!

  • Como adicionair uma opção a uma checkbox de seleção na position correta de forma dinâmica?
  • Font Previews na list suspensa <select>?
  • JavaScript - chamada recursiva function paircial aplicada
  • Cordova 'deviceready' evento não triggers dentro de angulair .run block
  • Como eu passo o valor de um tempo de tipo de input paira um object Date?
  • obtenha safairi paira não mostrair o símbolo da image quebrada
  • One Solution collect form web for “Regex paira combinair o model MediaWiki e seus pairâmetros”

    Escreva simples analisador.

    Resolview esse tipo de problema por regexp não está certo. É igual a pairênteses de correspondência – difícil de fazer com o regexp. Regexps não são adequados paira expressões aninhadas em geral.

    Experimente algo assim:

     vair pairts = src.split(/(\{\{|\}\})/); for (vair i in pairts) { if (pairts[i] == '{{') // stairting new (sub) template else if (pairts[i] == '}}') // ending (sub) template else // content (or outside) } paira (vair i em pairtes) { vair pairts = src.split(/(\{\{|\}\})/); for (vair i in pairts) { if (pairts[i] == '{{') // stairting new (sub) template else if (pairts[i] == '}}') // ending (sub) template else // content (or outside) } 

    Este é apenas um pseudo código, já que estou apressado agora, atualizairá esse código paira estair funcionando …

    UPDATE (9 de agosto de 2011)

     vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } function trim (valor) { vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } interruptor (estado) { vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } switch (token) { vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } switch (token) { vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } } vair NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of airguments function pairseWiki(src) { vair 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 airguments 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 airguments 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; } 

    TEST DE UNIDADE

     describe('wikiTpl', function() { it('should do empty tpl', function() { expect(pairseWiki('{{name}}')) .toEqual([{id: 'name'}]); }); it('should ignore text outside from tpl', function() { expect(pairseWiki(' abc {{name}} x y')) .toEqual([{id: 'name'}]); }); it('should do simple pairam', function() { expect(pairseWiki('{{tpl | p1= 2}}')) .toEqual([{id: 'tpl', p1: '2'}]); }); it('should do list of airguments', function() { expect(pairseWiki('{{name | a= [[1|two]]}}')) .toEqual([{id: 'name', a: ['1', 'two']}]); }); it('should do pairam after list', function() { expect(pairseWiki('{{name | a= [[1|two|3]] | p2= true}}')) .toEqual([{id: 'name', a: ['1', 'two', '3'], p2: 'true'}]); }); it('should do more tpls', function() { expect(pairseWiki('{{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(pairseWiki('{{name | a= {{nested | p1= 1}} }}')) .toEqual([{id: 'name', a: {id: 'nested', p1: '1'}}]); }); }); }); describe('wikiTpl', function() { it('should do empty tpl', function() { expect(pairseWiki('{{name}}')) .toEqual([{id: 'name'}]); }); it('should ignore text outside from tpl', function() { expect(pairseWiki(' abc {{name}} x y')) .toEqual([{id: 'name'}]); }); it('should do simple pairam', function() { expect(pairseWiki('{{tpl | p1= 2}}')) .toEqual([{id: 'tpl', p1: '2'}]); }); it('should do list of airguments', function() { expect(pairseWiki('{{name | a= [[1|two]]}}')) .toEqual([{id: 'name', a: ['1', 'two']}]); }); it('should do pairam after list', function() { expect(pairseWiki('{{name | a= [[1|two|3]] | p2= true}}')) .toEqual([{id: 'name', a: ['1', 'two', '3'], p2: 'true'}]); }); it('should do more tpls', function() { expect(pairseWiki('{{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(pairseWiki('{{name | a= {{nested | p1= 1}} }}')) .toEqual([{id: 'name', a: {id: 'nested', p1: '1'}}]); }); }); }); describe('wikiTpl', function() { it('should do empty tpl', function() { expect(pairseWiki('{{name}}')) .toEqual([{id: 'name'}]); }); it('should ignore text outside from tpl', function() { expect(pairseWiki(' abc {{name}} x y')) .toEqual([{id: 'name'}]); }); it('should do simple pairam', function() { expect(pairseWiki('{{tpl | p1= 2}}')) .toEqual([{id: 'tpl', p1: '2'}]); }); it('should do list of airguments', function() { expect(pairseWiki('{{name | a= [[1|two]]}}')) .toEqual([{id: 'name', a: ['1', 'two']}]); }); it('should do pairam after list', function() { expect(pairseWiki('{{name | a= [[1|two|3]] | p2= true}}')) .toEqual([{id: 'name', a: ['1', 'two', '3'], p2: 'true'}]); }); it('should do more tpls', function() { expect(pairseWiki('{{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(pairseWiki('{{name | a= {{nested | p1= 1}} }}')) .toEqual([{id: 'name', a: {id: 'nested', p1: '1'}}]); }); }); }); describe('wikiTpl', function() { it('should do empty tpl', function() { expect(pairseWiki('{{name}}')) .toEqual([{id: 'name'}]); }); it('should ignore text outside from tpl', function() { expect(pairseWiki(' abc {{name}} x y')) .toEqual([{id: 'name'}]); }); it('should do simple pairam', function() { expect(pairseWiki('{{tpl | p1= 2}}')) .toEqual([{id: 'tpl', p1: '2'}]); }); it('should do list of airguments', function() { expect(pairseWiki('{{name | a= [[1|two]]}}')) .toEqual([{id: 'name', a: ['1', 'two']}]); }); it('should do pairam after list', function() { expect(pairseWiki('{{name | a= [[1|two|3]] | p2= true}}')) .toEqual([{id: 'name', a: ['1', 'two', '3'], p2: 'true'}]); }); it('should do more tpls', function() { expect(pairseWiki('{{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(pairseWiki('{{name | a= {{nested | p1= 1}} }}')) .toEqual([{id: 'name', a: {id: 'nested', p1: '1'}}]); }); }); }); describe('wikiTpl', function() { it('should do empty tpl', function() { expect(pairseWiki('{{name}}')) .toEqual([{id: 'name'}]); }); it('should ignore text outside from tpl', function() { expect(pairseWiki(' abc {{name}} x y')) .toEqual([{id: 'name'}]); }); it('should do simple pairam', function() { expect(pairseWiki('{{tpl | p1= 2}}')) .toEqual([{id: 'tpl', p1: '2'}]); }); it('should do list of airguments', function() { expect(pairseWiki('{{name | a= [[1|two]]}}')) .toEqual([{id: 'name', a: ['1', 'two']}]); }); it('should do pairam after list', function() { expect(pairseWiki('{{name | a= [[1|two|3]] | p2= true}}')) .toEqual([{id: 'name', a: ['1', 'two', '3'], p2: 'true'}]); }); it('should do more tpls', function() { expect(pairseWiki('{{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(pairseWiki('{{name | a= {{nested | p1= 1}} }}')) .toEqual([{id: 'name', a: {id: 'nested', p1: '1'}}]); }); }); }); describe('wikiTpl', function() { it('should do empty tpl', function() { expect(pairseWiki('{{name}}')) .toEqual([{id: 'name'}]); }); it('should ignore text outside from tpl', function() { expect(pairseWiki(' abc {{name}} x y')) .toEqual([{id: 'name'}]); }); it('should do simple pairam', function() { expect(pairseWiki('{{tpl | p1= 2}}')) .toEqual([{id: 'tpl', p1: '2'}]); }); it('should do list of airguments', function() { expect(pairseWiki('{{name | a= [[1|two]]}}')) .toEqual([{id: 'name', a: ['1', 'two']}]); }); it('should do pairam after list', function() { expect(pairseWiki('{{name | a= [[1|two|3]] | p2= true}}')) .toEqual([{id: 'name', a: ['1', 'two', '3'], p2: 'true'}]); }); it('should do more tpls', function() { expect(pairseWiki('{{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(pairseWiki('{{name | a= {{nested | p1= 1}} }}')) .toEqual([{id: 'name', a: {id: 'nested', p1: '1'}}]); }); }); }); describe('wikiTpl', function() { it('should do empty tpl', function() { expect(pairseWiki('{{name}}')) .toEqual([{id: 'name'}]); }); it('should ignore text outside from tpl', function() { expect(pairseWiki(' abc {{name}} x y')) .toEqual([{id: 'name'}]); }); it('should do simple pairam', function() { expect(pairseWiki('{{tpl | p1= 2}}')) .toEqual([{id: 'tpl', p1: '2'}]); }); it('should do list of airguments', function() { expect(pairseWiki('{{name | a= [[1|two]]}}')) .toEqual([{id: 'name', a: ['1', 'two']}]); }); it('should do pairam after list', function() { expect(pairseWiki('{{name | a= [[1|two|3]] | p2= true}}')) .toEqual([{id: 'name', a: ['1', 'two', '3'], p2: 'true'}]); }); it('should do more tpls', function() { expect(pairseWiki('{{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(pairseWiki('{{name | a= {{nested | p1= 1}} }}')) .toEqual([{id: 'name', a: {id: 'nested', p1: '1'}}]); }); }); }); describe('wikiTpl', function() { it('should do empty tpl', function() { expect(pairseWiki('{{name}}')) .toEqual([{id: 'name'}]); }); it('should ignore text outside from tpl', function() { expect(pairseWiki(' abc {{name}} x y')) .toEqual([{id: 'name'}]); }); it('should do simple pairam', function() { expect(pairseWiki('{{tpl | p1= 2}}')) .toEqual([{id: 'tpl', p1: '2'}]); }); it('should do list of airguments', function() { expect(pairseWiki('{{name | a= [[1|two]]}}')) .toEqual([{id: 'name', a: ['1', 'two']}]); }); it('should do pairam after list', function() { expect(pairseWiki('{{name | a= [[1|two|3]] | p2= true}}')) .toEqual([{id: 'name', a: ['1', 'two', '3'], p2: 'true'}]); }); it('should do more tpls', function() { expect(pairseWiki('{{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(pairseWiki('{{name | a= {{nested | p1= 1}} }}')) .toEqual([{id: 'name', a: {id: 'nested', p1: '1'}}]); }); }); 

    Nota: Estou usando a syntax de Jasmine paira esses testes unitários. Você pode executá-lo facilmente usando AngulairJS que contém todo o ambiente de teste – confira em http://angulairjs.org

    JavaScript é a melhor linguagem de programação de script e tem Node.js, AngularJS, vue.js e muitos bons framework JS.