2011-08-02 5 views
4

구문 분석 문제가 발생했습니다.이 패턴은 작동하기 쉬운 패턴을 제외하면 재귀 적이어야합니다.
예 :.NET 용 대체 정규식 엔진, 재귀 지원

나는 그것을 일치시킬 어떤
{([^{}]*(?:{(?1)})?) 

, 특정 RTF 헤더이지만, 그렇게, 나는 그것이 재귀 할 필요가있다.

{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fnil\fcharset0 Tahoma;}} 

패턴의 이러한 종류의 (어쩌면 다른 문법)에 일치하는 항목을 찾을 수 있도록 할 .NET 비 진정한 정규식 같은 엔진 구현의 어떤 종류가 있습니까?

업데이트 :

정말 나에게 도움이되는 아래 주석으로 매우 포괄적 인 링크를 제공하고 정규 표현식의 .NET 구현, 특히 Qtax에있는 Balancing Group 옵션에 대해 저를 알리는 모두 감사드립니다 이것에 대한 모든 것을 이해하고 나의 구체적인 예에 ​​대한 답변을 게시하십시오. 당신이 이것을 읽고 있다면, 그것은 또한 당신을 도왔습니다, 그 대답을 upvote해야합니다.
그러나 ... .NET Regex 형 엔진에서 재귀 가능성에 대한 일반적인 질문에 답하지 못했습니다. 다행히도 (예를 들어, 도전을 좋아하는)이 예는 내가 만난 유일한 사람이 아닙니다. 그리고이 솔루션을 사용하여 다른 상황을 해결할 수는 없지만 일치 항목을 참조 할 수는 없지만 패턴 시퀀스를 재사용 할 수 있어야 재귀가 가능할 수 있습니다.

+2

을하는 동안 재귀에없는 직접적인 대답, [균형 잡힌 나무] (HTTP에 대한 .NET 지원 : // blogs.msdn.com/b/bclteam/archive/2005/03/15/396452.aspx)이이 문제에 유용 할 수 있습니다. – vcsjones

+1

매뉴얼의 밸런싱 그룹 : http://msdn.microsoft.com/en-us/library/bs2twtah.aspx#balancing_group_definition – Qtax

+0

네, 정말 도움이 되었어요. 고마워요. 그러나 재귀 적 정규 표현식이 필요할 때만이 그런 경우는 아닙니다. – AlexanderMP

답변

3

예를 들어 balancing group을 사용하면 효과가 있습니다.

당신은 같은 표현식 사용할 수

:

{ 
[^{}]* 
(?:({)[^{}]*)* 
(?'-1'})* 
(?(1)(?!)) 
} 

예 :

string re = @"{[^{}]*(?:({)[^{}]*)*(?'-1'})*(?(1)(?!))}"; 
string str = "foo {bar} baz {foo{bar{baz}}} {f{o{o}}{bar}baz} {foo{bar}baz}"; 

Console.WriteLine("Input: \"{0}\"", str); 
foreach (Match m in Regex.Matches(str, re)) 
{ 
    Console.WriteLine("Match: \"{0}\"", m); 
} 

출력 :

Input: "foo {bar} baz {foo{bar{baz}}} {f{o{o}}{bar}baz} {foo{bar}baz}" 
Match: "{bar}" 
Match: "{foo{bar{baz}}}" 
Match: "{o{o}}" 
Match: "{bar}" 
Match: "{bar}" 
+0

이 특정 질문에 대한 완전한 대답은 아니지만 가장 가까운 것이고 도움이되었습니다. 고맙습니다. – AlexanderMP

3

에도 Qtax의 exemple는 아주 좋은 분명하다, 일치하지 않았다을 나를 위해 완전히 {f{o{o}}{bar}baz} 대신 {o{o}}을 반환하기 때문에 완전히 나를 위해.

시간을 찾고 후, 내 솔루션은 (거의 같은 예제를 사용하여)입니다 :

입력 :

string re = @"{(((?<Counter>{)*[^{}]*)*((?<-Counter>})*[^{}]*)*)*(?(Counter)(?!))}"; 
string str = "foo {bar} baz {foo{bar{{baz}a{a{b}}}}} {f{o{o}}{bar{a{b{c}}{d}}}baz} {foo{bar}baz}"; 

Console.WriteLine("Input: \"{0}\"", str); 
foreach (Match m in Regex.Matches(str, re)) 
{ 
    Console.WriteLine("Match: \"{0}\"", m); 
} 

출력 :

Input: "foo {bar} baz {foo{bar{{baz}a{a{b}}}}} {f{o{o}}{bar{a{b{c}}{d}}}baz} {foo{bar}baz}" 
Match: "{bar}" 
Match: "{foo{bar{{baz}a{a{b}}}}}" 
Match: "{f{o{o}}{bar{a{b{c}}{d}}}baz}" 
Match: "{foo{bar}baz}" 

일부 설명, 나는 카운터를 증가 각 {에 대해 각각 }에서 카운터를 감소시킵니다. 마지막으로 카운터가 비어있는 경우에만 정규 표현식이 일치합니다 ((?(Counter)(?!))).

심한 재귀 및 대괄호로 작동하는 것처럼 보입니다.

이 정규식을 만드는 데 도움이되는 site을 참조하십시오.

도움이되기를 바랍니다.

PS : 당신이 말 사용에 잊어 버린와도 문자열} 일치 시키려면 :

string re = @"{(((?<Counter>{)*[^{}]*)*((?<-Counter>(}|$))*[^{}]*)*)*(?(Counter)(?!))(}|$)"; 
string str = "foo {bar} baz {foo{bar{{baz}a{a{b}}}}} {f{o{o}}{bar{a{b{c}}{d}}}baz} {foo{bar}b{az";