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}"
]

これは、最初の開き角かっこを繰り返し検索し、次に最初の閉じかっこasoを検索することで実行できることを知っています。しかし、それよりもエレガントな解決策はありません(おそらく正規表現の魔法ですか?)。

4

1 に答える 1

4

正規表現分割を使用して、必要な配列を取得できます。

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

{およびは正規表現でリテラル}としてエスケープする必要があります\{。これはJava文字列であるため、これらのsはさらにエスケープする必要があります。)\}\\\

つまり、先読み{ix:または後読みし}、見つかった場合はその位置で分割します。

他の状況で有効である可能性がある場合}、私はおそらく別のアプローチを取るでしょう。

見回し

正規表現の忘れられがちな側面は、特に分割に関しては、位置を一致させることができることです。これは、ゼロ幅一致とも呼ばれます。

^ほとんどの人は、やのような位置の一致に精通して\bいますが、アドホックな条件を指定できるルックアラウンドに精通している人はほとんどいません。

正規表現に位置一致構造のみが含まれている場合、一致に文字は含まれていませんが、正規表現は一致が発生した位置を記録します-ほとんどの文字列操作には位置と長さが必要であり、長さが0の場合でも分割が可能です(または交換)指定された位置で発生します。

先読みと後読みを使用すると、テスト対象の位置から文字列の前方(前方)と後方(後方)にチェックされる部分式を指定することにより、位置を一致させることができます。

構文用語では、先読みはのように見えます(?=subexpr)が、後読みはのように見えます(?<=subexpr)

否定されたバージョンがあります-パターンが成功したと見なされないようにする必要がある場合-それぞれ(?!subexpr)(?<!subexpr)です。

ルックアラウンドはキャプチャされません。それらの一致は、標準のように後方参照グループに配置されません(group)が、後方参照を含めることができます。

制限の背後にあるもの

Java *のルックビハインドには、長さを無制限にすることはできないという制限があります。そのため、無制限にすることはできません(?<=\w+)が、代わりに上限のある数値数量詞を使用する必要があります。(?<=\w{1,99}

(*いくつかの正規表現の実装にはこの制限はありませんが、多くの場合、固定長であるというより厳しい制限があります。)

先読みにはそのような制限はありません(もちろん、パフォーマンス上の理由から、必要なものだけに一致するように制限する必要があります)。

于 2012-12-12T18:28:11.307 に答える