私の正規表現は**(A)(([+-]\d{1,2}[YMD])*)**
、A + 3M、A-3Y + 5M + 3Dなどのように期待どおりに一致するこのようなものです。
しかし、このサブパターンのすべてのグループをキャプチャしたい**([+-]\d{1,2}[YMD])***
次の例A-3M + 2Dの場合、4つのグループしか表示できません。A-3M+2D (group 0), A(group 1), -3M+2D (group 2), +2D (group 3)
**-3M**
別のグループとして取得する方法はありますか?
繰り返されるキャプチャグループは通常、最後の反復のみをキャプチャします。言語には各キャプチャグループスタックを追跡するメソッドがないため、これはKotlinとJavaに当てはまります。
回避策として実行できることは、最初に文字列全体を、文字列が一致する必要がある特定のパターンに対して検証してから、文字列を抽出するか、部分に分割することです。
現在のシナリオでは、次を使用できます
val text = "A-3M+2D"
if (text.matches("""A(?:[+-]\d{1,2}[YMD])*""".toRegex())) {
val results = text.split("(?=[-+])".toRegex())
println(results)
}
// => [A, -3M, +2D]
ここに、
text.matches("""A(?:[+-]\d{1,2}[YMD])*""".toRegex())
文字列全体が一致することを確認してA
から、0個以上の+
or -
、1桁または2桁の後にY
、M
またはD
.split("(?=[-+])".toRegex())
-
またはの直前の空の文字列でテキストを分割します+
。パターンの詳細
^
-暗黙的.matches()
-文字列の開始A
-A
部分文字列(?:
-非キャプチャグループの開始:
[+-]
-一致する文字クラス+
または-
\d{1,2}
-1〜2桁[YMD]
-文字クラスと一致するY
か、M
またはD
)*
-非キャプチャグループの終わり、0回以上繰り返します(*
定量化のため)\z
-暗黙的matches()
-文字列の終わり。分割は、私たちは前に場所を見つける必要があるとき-
や+
、それゆえ我々は積極的に利用先読みを、(?=[-+])
、それはすぐに続いている位置と一致する+
かを-
。これは消費しないパターンであり、+
または-
一致したものは一致値に追加されません。
単一の正規表現を使用した別のアプローチ
また、\G
ベースの正規表現を使用して、文字列の先頭で最初に文字列形式をチェックし、そのチェックが成功した場合にのみ、連続する部分文字列の照合を開始することもできます。
val regex = """(?:\G(?!^)[+-]|^(?=A(?:[+-]\d{1,2}[YMD])*$))[^-+]+""".toRegex()
println(regex.findAll("A-3M+2D").map{it.value}.toList())
// => [A, -3M, +2D]
別のKotlinデモと正規表現デモを参照してください。
詳細
(?:\G(?!^)[+-]|^(?=A(?:[+-]\d{1,2}[YMD])*$))
-前回の正常な一致の終了後、+
または-
(を参照\G(?!^)[+-]
)または(|
)文字列の開始の後A
に+
/ -
、1桁または2桁の出現が0回以上続いた後Y
、M
またはD
文字列の終了まで(を参照)^(?=A(?:[+-]\d{1,2}[YMD])*$)
)[^-+]+
--
および以外の1つ以上の文字+
。先読みは弦の始めに重い物を持ち上げたので、ここではあまり注意する必要はありません。この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加