2017-06-15 6 views
2

サブルーチンを呼び出すことは可能だが、その呼び出しの結果をキャプチャすることはできないのだろうかと思っていた。例えば非キャプチャサブルーチン

、のは、私は再帰的に

{dfsdf {sdfdf {{dfsdf}}} dfsf}

私が使用することができ

のようなバランスブラケット{}構造と一致してキャプチャしたいとしましょうこの正規表現:

最初のグループは私がキャプチャしたいものです。

しかし巣 "の私の定義:

(?'nest' ...) 

と '巣' サブルーチンへの私の再帰呼び出し:

(?&nest) 

もグループをキャプチャしています。私は正規表現をより効率的にし、それらのグループをキャプチャしないことでスペースを節約したいと思います。これを行う方法はありますか?

編集:サブルーチンの定義をキャプチャすることは不可能です。そのパターンは、別の場所で使用するためにキャプチャする必要があるためです。


EDIT2:

私はブースト::正規表現だけでなく、メモ帳++正規表現でこの正規表現をテストしています。彼らは実際に私には奇妙な異なるキャプチャグループを定義しているようです。私は彼らがデフォルトでPerlの正規表現を使用しているという印象を受けています。

^\w+\s+[^\s]+\s+(?'header'(?'nest'\{(?>[^{}]|(?&nest))*\}))(?>\s+[^\s]+){5}\s+(?'data'(?>\{(?>[^{}]|(?&nest))*\}))\s+(?'class'(?>\{(?>[^{}]|(?&nest))*\})) 

私は、後に「巣」はすでにカプセル化されたことを不必要な文字が含まれて実現:

はとにかく、質問をすると、私は正規表現を持っていました。そして、私が今持っている:

^\w+\s+[^\s]+\s+(?'nest'\{(?>[^{}]|(?&nest))*\})(?>\s+[^\s]+){5}\s+((?&nest))\s+((?&nest)) 

メモ帳++は、私はそれが私に語ったREPLACE文

\\1: \1 \n \\2: \2 \n 3: \3 \n 4: \4 

を行う際に「1件の発生が交換された、次の発生は見られない」3つのキャプチャグループで私を提供します。 4:の後に置換えのテキストがないので、4番目のキャプチャグループが存在しないと私に信じさせます。

もつともブースト:: 6つの位置にオブジェクトを返すregex_match:

0:マッチに対するメタデータ

1:全体のマッチ

2:全体の一致

3: group1 from notepad ++

4:notepadからのグループ2 ++

5:私は、パズルのさらに別の部分を誤解し、私はまだポジション1の送信と2


EDIT3

を作成しようとしている

++メモ帳からグループ3 ...

boost :: cmatch.m_subs [i]!boost :: cmatch [i]

私はそれらが等しいと思った。もう少しデバッグした後、オブジェクトへのインデックス付けは、ドキュメントの説明どおりに動作します。しかし、私は間違って、オブジェクトにboost :: cmatch [i]が返すものを反映する構造体を含むと仮定しました。 boost :: cmatch [i]はまず、== falseにマッチしたm_subsからすべてのエントリを削除します。残りのエントリは、boost :: cmatch [i]が返すものと並んでいます。

+0

文字列の先頭にある '{...}'平衡部分文字列と一致する必要がある場合は、非取得サブルーチン呼び出しを使用する方法がありません。 –

+0

これには何らかの理由がありますか?その機能は正規表現の機能性を向上させるようです。 – Derek

+0

私はむしろ早すぎる最適化と呼んでいます。 –

答えて

1

どれサブルーチンが置か(?。(DEFINE))コンストラクトは何をキャプチャしません

あなただけの任意のキャプチャを持つ避けたい場合は、この

https://regex101.com/r/aT4TlM/1

ノートのように行われています - 。

サブパターンの定義(?(DEFINE)(?'nest'\{(?>[^{}]|(?&nest))*\}))
だけの機能を定義するために使用され得る構築。このグループでは一致しません。

^(?&nest)(?(DEFINE)(?'nest'\{(?>[^{}]|(?&nest))*\}))

そして、あなたはBOSのアンカーは、それが唯一の方法ですが^ことを持っているからです。
I. (?R)はオプションではありません。

拡張

^
(?&nest) 

(?(DEFINE) 

     (?'nest'      # (1 start) 
      \{ 
      (?> 
       [^{}] 
      | (?&nest) 
      )* 
      \} 
    )        # (1 end) 
) 

出力

** Grp 0  - (pos 0 , len 29) 
{dfsdf{sdfdf{ {dfsdf} }}dfsf} 
    ** Grp 1 [nest] - NULL 

メトリック

---------------------------------- 
* Format Metrics 
---------------------------------- 
Atomic Groups  = 1 

Capture Groups  = 1 
     Named  = 1 

Recursions   = 2 

Conditionals  = 1 
     DEFINE  = 1 

Character Classes = 1 
+0

すべての情報をありがとう、私は何が起こっていたかをよりよく記述するために私の質問を編集しました。 – Derek

1

サブルーチンコールは、サブパターンを再帰的に呼び出すメカニズムです。正規表現エンジンは、どのグループが再帰するかを知っていなければならず、そのためID(グループがの場合は)または名前(あなたの場合のように名前付きグループの場合)が必要です。 非キャプチャグループは、これらのグループパターンへの参照を格納しないため、サブルーチンコールの中で参照することはできません。

サブルーチン呼び出しでキャプチャグループを使用しないための唯一の方法は、(?R)パターン全体へのショートカットを使用することです。しかし、あなたが文字列の先頭にマッチし、唯一^後のパターンの一部を再帰的にしたいあなたの場合のように、パターン(の一部を再帰的にする必要はオプションではありません。

+0

クイック返信ありがとうございます。私は深い誤解があったことを反映するために質問を延長しました。 – Derek

+0

@Derekご覧のとおり、DEFINEブロックでも、キャプチャグループを使用してサブパターンを定義します。唯一の違いは、キャプチャが一致結果に返されないことです。 **パターンを反復する必要がある場合は、キャプチャグループとしてパターンを定義することを避けることはできません**、一致結果の中にマスクすることはできません。 –

1

日時:EDIT2

この正規表現^\w+\s+[^\s]+\s+(?'nest'\{(?>[^{}]|(?&nest))*\})(?>\s+[^\s]+){5}\s+((?&nest))\s+((?&nest))

は、3つのグループのみを含むようにフォーマットされているときに表示されます。

^\w+ \s+ [^\s]+ \s+ 
(?'nest'      # (1 start) 
     \{ 
     (?> 
      [^{}] 
     | (?&nest) 
    )* 
     \} 
)        # (1 end) 
(?> \s+ [^\s]+){5} 
\s+ 
((?&nest))     # (2) 
\s+ 
((?&nest))     # (3) 

これで何をしたいですか?

+0

それは意図どおり正確に動作します...私の元の正規表現は間違っていましたが、私は正しく書かれていると想定し、不適切なグループ分けは私の正規表現ではなく、基礎となるソフトウェアの症状でした。これは、VS2013でデバッグ中に表示されるboost :: cmatchオブジェクトの誤った解釈によって悪化しました。 – Derek

+0

ええ、docsのように見えます.'''型のオブジェクトはmatch_results型のオブジェクトに添字をつけることでしか得られません '' match_results [I]から得られたsub_matchは、グループについての情報を得るメソッドを含んでいます。イテレータのfirst/last(string(m [2] .first、m [2] .second))、boolとマッチしたもの、m [2] .basic_string()のような他の直接的な文字列の変換また、位置と長さ。 – sln

+0

私がsub_matchを使うとき、時々私はこのレベルの '(int)_m [i] .first._Ptr'まで深くなり、他の長さや場所、または無関係なオフセットと直接比較します。 – sln

関連する問題