3

我正在构建一个非常简单的模板处理器。它只能替换变量的值。

我想我会首先将字符串分解成部分(常量部分和变量引用)。然后我会用相应的值替换所有变量引用。最后,我会将所有部分重新连接在一起。


为了分解字符串,我需要按以下方式对其进行切片。

像这样的字符串

"UPDATE {ix:tablename} SET value = value + 1 WHERE {ix:column} = {ix:value}"

应该导致以下数组

[
  "UPDATE ",
  "{ix:tablename}",
  " SET value = value + 1 WHERE ",
  "{ix:column}",
  " = ",
  "{ix:value}"
]

我知道这可以通过重复搜索第一个左括号,然后是第一个右括号来完成。但是没有比这更优雅的解决方案(也许是一些正则表达式的魔法?)。

4

1 回答 1

4

您可以使用正则表达式拆分获得所需的数组:

MyString.split("(?=\\{ix:)|(?<=\\})")

{and}需要在正则表达式中转义为\{and ,因为它是一个 Java 字符串,所以s 需要进一步转义为。)\}\\\

即前瞻{ix:或后视}并在该位置拆分(如果找到)。

如果有可能}在其他情况下有效,我可能会采取不同的方法。

环顾四周

正则表达式的一个经常被遗忘的方面,特别是在拆分时,是它可以匹配位置,也称为零宽度匹配。

大多数人都熟悉位置匹配,例如^and \b,但很少有人熟悉允许指定临时条件的环视。

当一个正则表达式只包含位置匹配结构时,虽然匹配中不包含任何字符,但正则表达式仍然记录匹配发生的位置——大多数字符串操作只需要一个位置和一个长度,长度为 0 仍然允许拆分 (或更换)发生在指定位置。

Lookaheads 和lookbehinds 允许您通过指定子表达式来匹配位置,这些子表达式从正在测试的位置开始在字符串中向前(向前)和向后(向后)检查。

在语法方面,前瞻看起来像(?=subexpr),而后瞻看起来像(?<=subexpr).

有否定的版本 - 当模式必须失败时被认为是成功的 - 分别是(?!subexpr)(?<!subexpr)

Lookarounds 是非捕获的——它们的匹配不会像 standard 那样放在反向引用组中(group),尽管它们可以包含反向引用。

后视限制

Java* 中的 Lookbehinds 有一个限制,即它们不能是无限长度 - 所以你不能这样做(?<=\w+),而是需要使用具有上限的数字量词,例如(?<=\w{1,99}

(*几个正则表达式实现没有这个限制;尽管许多有更严格的固定长度限制。)

Lookaheads 没有这样的限制(当然,出于性能原因,您应该将它们限制为仅匹配所需的内容)。

于 2012-12-12T18:28:11.307 回答