Luaでは、パターンマッチングとキャプチャを試みています。
+384 Critical Strike (Reforged from Parry Chance)
なので
(+384) (Critical Strike)
ここで、接尾辞(Reforged from %s)
はオプションです。
ロングバージョン
パターンを使用してLuaの文字列を照合しようとしています(つまり)strfind
注:Luaでは、正規表現とは呼ばれません。正規表現ではないため、パターンと呼ばれます。
文字列の例:
+384 Critical Strike
+1128 Hit
これは、キャプチャしたい2つの部分に分けられます。
- 数字、先頭に正または負のインジケーターが付いています。彼の場合は
+384
- この場合の文字列
Critical Strike
はです。
かなり単純なパターンを使用してこれらをキャプチャできます:
そして、luaのこのパターンは機能します:
local text = "+384 Critical Strike";
local pattern = "([%+%-]%d+) (.+)";
local _, _, value, stat = strfind(text, pattern);
- 値=
+384
- stat =
Critical Strike
トリッキーな部分
次に、その正規表現 パターンを拡張して、オプションの接尾辞を含める必要があります。
+384 Critical Strike (Reforged from Parry Chance)
これは次のように分類されます。
注:オプションの末尾の接尾辞は特に気にしません。つまり、キャプチャする必要はありませんが、キャプチャすると便利です。
ここから、貪欲なキャプチャの問題が発生し始めます。すぐに、私がすでに持っているパターンは、私が望まないことを実行します。
- パターン=
([%+%-]%d+) (.+)
- 値=
+384
- stat =
Critical Strike (Reforged from Parry Chance)
しかし、パターンに接尾辞を含めてみましょう。
パターンで:
pattern = "([%+%-]%d+) (.+)( %(Reforged from .+%))?"
そして、私は接尾辞の出現?
を示すために演算子を使用していますが、0
それは何にも一致しません。1
オプションのサフィックスグループをかっこから角かっこに変更しようとしまし(
た[
:
pattern = "([%+%-]%d+) (.+)[ %(Reforged from .+%)]?"
しかし今、試合は再び貪欲です:
- 値=
+384
- stat =
Critical Strike (Reforged from Parry Chance)
Luaパターンリファレンスに基づく):
- x :(ここでxは魔法の文字の1つではありません^$()%。[] * +-?)は文字x自体を表します。
- 。:(ドット)はすべての文字を表します。
- %a:すべての文字を表します。
- %c:すべての制御文字を表します。
- %d:すべての桁を表します。
- %l:すべて小文字を表します。
- %p:すべての句読文字を表します。
- %s:すべてのスペース文字を表します。
- %u:すべて大文字を表します。
- %w:すべての英数字を表します。
- %x:すべての16進数を表します。
- %z:表現0の文字を表します。
- %x:(xは英数字以外の文字)は文字xを表します。これは魔法のキャラクターを逃れるための標準的な方法です。パターンでそれ自体を表すために使用される場合、句読文字(非魔法であっても)の前に「%」を付けることができます。
- [set]:セット内のすべての文字の和集合であるクラスを表します。文字の範囲は、範囲の終了文字を「-」で区切ることによって指定できます。上記のすべてのクラス%xは、セット内のコンポーネントとしても使用できます。セット内の他のすべての文字は、それ自体を表します。たとえば、[%w _](または[_%w])はすべての英数字とアンダースコアを表し、[0-7]は8進数を表し、[0-7%l%-]は8進数と小文字を表します。文字と「-」文字。範囲とクラス間の相互作用は定義されていません。したがって、[%az]や[a-%%]のようなパターンには意味がありません。
- [^ set]:setの補集合を表します。ここで、setは上記のように解釈されます。
単一文字(%a、%cなど)で表されるすべてのクラスの場合、対応する大文字はクラスの補集合を表します。たとえば、%Sはすべての非スペース文字を表します。
文字、スペース、およびその他の文字グループの定義は、現在のロケールによって異なります。特に、クラス[az]は%lと同等ではない場合があります。
と魔法のマッチャー:
*
、クラス内の文字の0回以上の繰り返しに一致します。これらの繰り返し項目は、常に可能な限り長いシーケンスに一致します。+
、クラス内の文字の1回以上の繰り返しに一致します。これらの繰り返し項目は、常に可能な限り長いシーケンスに一致します。-
、これは、クラス内の0回以上の文字の繰り返しにも一致します。'*'とは異なり、これらの繰り返し項目は常に可能な限り短いシーケンスに一致します。?
、クラス内の文字の0または1回の出現に一致します。
欲張りな修飾子と欲張りでない修飾 *
子があることに気づきました。私のミドルストリングマッチャー以来: -
(%d) (%s) (%s)
最後までテキストを吸収しているようです。おそらく、を:に変更して、貪欲でないようにする必要があります。*
-
oldPattern = "([%+%-]%d+) (.*)[ %(Reforged from .+%)]?"
newPattern = "([%+%-]%d+) (.-)[ %(Reforged from .+%)]?"
今を除いて、それは一致しません:
- 値=
+384
- stat = nil
中間グループが「任意の」文字(つまり)をキャプチャするのではなく、以下を除く.
すべてを含むセットを試しました。 (
pattern = "([%+%-]%d+) ([^%(]*)( %(Reforged from .+%))?"
そしてそこから車輪が荷馬車から外れました:
local pattern = "([%+%-]%d+) ([^%(]*)( %(Reforged from .+%))?"
local pattern = "([%+%-]%d+) ((^%()*)( %(Reforged from .+%))?"
local pattern = "([%+%-]%d+) (%a )+)[ %(Reforged from .+%)]?"
私は私が近くにいると思った:
local pattern = "([%+%-]%d+) ([%a ]+)[ %(Reforged from .+%)]?"
キャプチャします
- value = "+385"
- stat = "Critical Strike " (notice the trailing space)
だから、これは私が枕に頭をぶつけて寝るところです。この正規表現に4時間を費やしたなんて信じられません...パターン。
@NicolBolas疑似正規表現言語を使用して定義された、可能なすべての文字列のセットは次のとおりです。
+%d %s (Reforged from %s)
どこ
+
プラス記号(+
)または「マイナス記号」()のいずれかを表します-
%d
ラテン数字を表します(例0..9
)%s
ラテン語の大文字または小文字、または埋め込みスペースを表します(例A-Za-z
)- 残りの文字はリテラルです。
明らかに私がやりたいことをやろうとする正規表現を書かなければならなかった場合:
\+\-\d+ [\w\s]+( \(Reforged from [\w\s]+\))?
しかし、私がそれを十分に説明しなかった場合、私が野生で遭遇する可能性のあるすべての値のほぼ完全なリストをあなたに与えることができます。
+123 Parry
正の数、一言+123 Critical Strike
正の数、2つの単語-123 Parry
負の数、一言-123 Critical Strike
負の数、2ワード+123 Parry (Reforged from Dodge)
正の数、単一の単語、単一の単語に存在するオプションの接尾辞+123 Critical Strike (Reforged from Dodge)
正の数、2語、2語のオプションの接尾辞-123 Parry (Reforged from Hit Chance)
負の数、1つの単語、2つの単語を含むオプションの接尾辞-123 Critical Strike (Reforged from Hit Chance)
負の数、2語、2語のオプションの接尾辞
ボーナスパターンがあり、パターンも一致することは明らかです。
+1234 Critical Strike Chance
4桁の数字、3つの単語+12345 Mount and run speed increase
5桁の数字、5つの単語+123456 Mount and run speed increase
6桁の数字、5つの単語-1 MoUnT aNd RuN sPeEd InCrEaSe
1桁の数字、5つの単語-1 HiT (Reforged from CrItIcAl StRiKe ChAnCe)
負の1桁の数字、1ワード、3ワードのオプションの接尾辞
理想的なパターンは上記のボーナスエントリと一致する必要がありますが、一致する必要はありません。
ローカリゼーション
実際には、私が解析しようとしているすべての「数値」はローカライズされます。例:
+123,456
英語(en-US)+123.456
ドイツ(de-DE)+123'456
フランス語(fr-CA)+123 456
エストニア語(et-EE)+1,23,456
アッサム語(as-IN)
いかなる回答も、これらのローカリゼーションの問題を説明しようとしてはなりません。番号が表示されるロケールがわからないため、番号のローカリゼーションが質問から削除されました。数字には、、、およびラテン数字から。までが含まれていると厳密に想定する必要があります。ローカライズされた数値を解析する方法はすでに知っています。この質問は、オプションのサフィックスを貪欲なパターンパーサーと一致させようとすることに関するものです。plus sign
hyphen minus
0
9
編集:あなたは本当にローカライズされた番号を処理しようとする必要はありませんでした。あるレベルでは、ロケールを知らずにそれらを処理しようとするのは間違っています。たとえば、考えられる数字のローカリゼーションをすべて含めたわけではありません。もう1つは、将来どのようなローカリゼーションが存在するかわかりません。