在bbcode标记之外的文本中添加标记

时间:2018-08-21 07:01:13

标签: javascript regex parsing bbcode

我有一个我无法回答的问题。我编写了BBCODE编辑器,并且在WYSIWYG编辑器和代码编辑器之间切换。

视觉编辑器是通过拖放式方块系统(图片,文本等)构建的

在可视编辑器中,当用户拖动新的文本块时,内容将自动写入[text][/text]标签之间。

在代码编辑器中,用户可以编写没有[text][/text]标签的自由文本。

要能够在两个编辑器之间切换,需要在代码编辑器的[text][/text]标签之间添加自由文本。

示例

我在代码编辑器中编写文本和bbcode:

Cum haec taliaque sollicitas eius aures everberarent expositas semper eius modi
rumoribus et patentes.
[img]https://foo.com/fighters.png[/img]
Denique Antiochensis ordinis vertices sub uno elogio iussit occidi ideo efferatus,
quod ei celebrari vilitatem intempestivam urgenti, cum inpenderet inopia
[img]https://foo.com/fighters1.png[/img]
[img]https://foo.com/fighters2.png[/img]
Utque proeliorum periti rectores [i]primo catervas[/i] densas opponunt et fortes,
deinde leves armaturas, post iaculatores ultimasque subsidiales acies, si fors
adegerit

如果我切换到可视化编辑器,则需要在[text][/text]之间添加自由文本,如下所示:

[text]Cum haec taliaque sollicitas eius aures everberarent expositas semper eius modi
rumoribus et patentes.[/text]
[img]https://foo.com/fighters.png[/img]
[text]Denique Antiochensis ordinis vertices sub uno elogio iussit occidi ideo efferatus,
quod ei celebrari vilitatem intempestivam urgenti, cum inpenderet inopia[/text]
[img]https://foo.com/fighters1.png[/img]
[img]https://foo.com/fighters2.png[/img]
[text]Utque proeliorum periti rectores [i]primo catervas[/i] densas opponunt et fortes,
deinde leves armaturas, post iaculatores ultimasque subsidiales acies, si fors
adegerit[/text]

我认为有两种方法:

  • 使用循环分割文本和bbcode,并使用另一个循环重建代码。
  • 使用正则表达式获取自由文本并替换它。

最好的方法是什么?您认为可以从正则表达式添加标签吗?

谢谢你, 托马斯

1 个答案:

答案 0 :(得分:1)

尝试一下:

const regex = /(\[(img|\w{4,})\][\s\S]*?\[\/\2\])(\n?)|([\s\S]+?)(\n?)(?=$|\[(?:img|\w{4,})\])/gi;
let str = `
Cum haec taliaque sollicitas eius aures everberarent expositas semper eius modi
rumoribus et patentes.
[image]https://foo.com/fighters.png[/image]
Denique Antiochensis ordinis vertices sub uno elogio iussit occidi ideo efferatus,
quod ei celebrari vilitatem intempestivam urgenti, cum inpenderet inopia
[image]https://foo.com/fighters1.png[/image]
[image]https://foo.com/fighters2.png[/image]
Utque proeliorum periti rectores [i]primo catervas[/i] densas opponunt et fortes,
deinde leves armaturas, post iaculatores ultimasque subsidiales acies, si fors
adegerit`;
   

let m;
let outstr = '';

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) { regex.lastIndex++; }
   
    // The result can be accessed through the `m`-variable.
    // m[1] == structure tags
    // m[4] == text content
    // m[3] nad m[5] are new lines (if present)
    if (typeof m[1] != 'undefined') {
        outstr += m[1] + m[3];
    }
    else {
        outstr += '[text]' + m[4] + '[/text]' + m[5];
    }
}
console.log(outstr);

在正则表达式上,您使用第一个捕获组来摆脱结构标签。第二组为其余数据。如果第一组有数据,则意味着我们找到了结构标签。我们只是积累它。如果不是,则表示它是文本。因此,我们使用新的[text]标签

对其进行了累积。

最后,在第3和第5个捕获组中,有新行(如果存在)

第二个捕获组用于使开始和结束标签相等。

Demo on regex101

正则表达式解释:

  # First option: an structural tag ([image]...[/image]
  ( # First capturing group
    \[ # Literal '['
      (img|\w{4,}) # img tag or tag with 4 or more letters (all structural tags)
    \] # Literal ']'
    [\s\S]*? # Any character 0 or more times, ungreedy
    \[\/\2\] # Closing tag. Word = same as opening tag
  )(\n?) # a new line may appear. Save it on third capturing group

  # Second option: other text
| ([\s\S]+?) # Any character 1 or more times, ungreedy. Third capturing group
  (\n?)      # A new line may appear, Don't want it on the previous group
  (?=        # Lookahead. The following must appear (but we don't match it)
       $  # Either end of line
     | \[(?:img|\w{4,})\] # or some opening structural tag
  )