我正在构建一个非常简单的模板处理器。它只能替换变量值。
我以为我会首先将字符串分解为部分(常量部分和变量引用)。然后我会用相应的值替换所有变量引用。最后,我将所有部分连接在一起。
为了分解字符串,我需要按以下方式对其进行切片。
像这样的字符串
"UPDATE {ix:tablename} SET value = value + 1 WHERE {ix:column} = {ix:value}"
应该产生以下数组
[
"UPDATE ",
"{ix:tablename}",
" SET value = value + 1 WHERE ",
"{ix:column}",
" = ",
"{ix:value}"
]
我知道这可以通过反复搜索第一个开口括号,然后是第一个右括号aso来完成。但是,有没有比这更优雅的解决方案(一些正则表达式的魔法,也许?)。
答案 0 :(得分:4)
您可以通过正则表达式拆分获得所需的数组:
MyString.split("(?=\\{ix:)|(?<=\\})")
({
和}
需要转义为\{
和\}
在regex中是文字的,因为它是一个Java字符串\
1}}需要进一步转义为\\
。)
即。 {ix:
的前瞻或}
的后瞻,如果找到,则在该位置拆分。
如果}
可能在其他情况下有效,我可能采取不同的方法。
正则表达式的常见问题,特别是在分裂时,它可以匹配位置,也称为零宽度匹配。
大多数人都熟悉位置匹配,例如^
和\b
,但很少有人熟悉外观,这些内容允许指定临时条件。
当正则表达式只包含位置匹配结构时,虽然匹配中不包含任何字符,但正则表达式仍会记录发生匹配的位置 - 大多数字符串操作只需要一个位置和一个长度,并且长度为0仍允许在指定位置进行拆分(或替换)。
Lookaheads和lookbehinds允许您通过指定从正在测试的位置向前(向前)和向后(向后)检查的子表达式来匹配位置。
在语法术语中,前瞻看起来像(?=subexpr)
,而后视看起来像(?<=subexpr)
。
存在否定版本 - 因为模式必须被认为不成功 - 分别是(?!subexpr)
和(?<!subexpr)
。
Lookarounds是非捕获的 - 它们的匹配不放在后向引用组中,如标准(group)
,但它们可以包含反向引用。
Java *中的Lookbehinds有一个限制,它们不能无限长 - 所以你不能做(?<=\w+)
而是需要使用带有上限的数字量词,例如(?<=\w{1,99}
(*一些正则表达式的实现没有这个限制;尽管许多人对固定长度有更严格的限制。)
Lookaheads没有这样的限制(当然,出于性能原因,你应该限制它们只匹配所需的)。