2016-05-20 2 views
1

regexpに失敗してしまいました。 (外$を取って、それの亜種など)をファイル名の部分をキャプチャ:なぜこの正規表現は機能しませんか?

test.orange.john (which is the body) 
edn (which is the extension) 

私はこれを使用:

のは、私は2つのグループをキャプチャすること

test.orange.john.edn 

のようなファイルパスを持っているとしましょう

^([a-z]*.)*.([a-z]*$) 

しかし、それは唯一の

XMをキャプチャ

私は何を欠席しましたか? Lがキャプチャされていない理由を私は理解していないと体があまりにも... 私は拡張子をキャプチャするために、ウェブ上で答えを見つけましたが、私はそこに問題を理解していません。

おかげ

+2

。 ['^(。*)\。([az] * $) '](https://regex101.com/r/pO8lS7/1)または[' ^(。*)\。(。*)$ '](https://regex101.com/r/p08lS7/2)が実行されます。 –

+0

ああ、おかげでドットが構文で使われているのを知らなかった –

答えて

2

^([a-z]*.)*.([a-z]*$)正規表現は、ここで不要なバックトラックのステップがたくさんあるように非常に非効率的です。

文字列の先頭を一致させ、その後、[a-z]*.は0+回マッチしています。つまり、エンジンはできるだけ多く[a-z]に一致します(つまり、最初のドットまではtestと一致します)。.はドットに一致します(ただし、.は任意の文字に一致します)。だから、この([a-z]*.)*はキャプチャグループのみが最後に撮影した値を保つ繰り返すので、ednをキャプチャtest.orange.john.ednのみ一致します。

あなたは既にグループ1 at this stepednを持っています。今、.([a-z]*$)は、.(任意の文字)パターンの部分文字列を割り当てる必要があります。バックトラッキングが戻ってn - Group 1 only contains edになりました。あなたのタスクのために

、あなたはリテラルドットに一致するように、最後の.をエスケープする必要があり、おそらく、最高の表現は

^(.*)\.(.*)$ 

それはまでのすべての文字列にマッチしますdemo

を参照してくださいです最後に.シンボルが見つかるようにバックトラックします(したがって、グループ1は最初から最後まで.までのすべてのテキストを持ちます)。残りの文字列をグループ2にキャプチャします。

ドットが存在する必要がない場合(すなわち、ファイル名には拡張子がない場合)、オプションのグループを追加します。

^(.*)(?:\.(.*))?$ 

を参照してくださいanother demo

はリテラルのドットに一致するようにドットをエスケープ
+0

ああ、今はドットの使用を理解しています。とだけでなく、az! –

0

あなたがして試すことができます:

^([a-z.]+)\.([a-z]+)$ 

online example

+0

ありがとう、私は[]の意味を忘れてしまった。特定のファイルには名前がないので最初の+を置き換えただけです^([az。] *)\。([az] +)$ –

関連する問題