2013-06-06 3 views
1

'컨트롤 시퀀스'가있는 html이 이미 있습니다. 콘텐츠에서 html 태그를 이미 제거 했으므로 이제 '컨트롤 시퀀스'를 '스타일'로 바꾸고 싶습니다. 지금까지그룹 캡쳐, 그룹당 많은 그룹

html 태그가 I이이 제거 된 후

...

"<!C43!><!TG!>Some Characters" 
궁극적으로이 생산하는

...

<span class="C43 TG">Some Characters</span> 

내 결함 C 번호 :

Regex reg = new Regex("<!([^<>]+?)!>"); 

Match matches = reg.Match(line); 
foreach (Group group in matches.Groups) 
{ 
    // finds both groups, 
    // and remove the control sequence 
} 

내가 breakboint로 검사 할 때 다음 그룹을 잘못 반환하기 때문에 나는 'foreach'에서 많은 것을 얻지 못했다 ...

Group 1 : <!C43!> 
Group 2 : C43 
<it does not find second group :(> 

는 어떤 도움을 주시면 감사하겠습니다,하지만 난 주로 내가 문자열을 찾고 있어요 찾을 수있는 올바른 정규식을 찾고 있어요,하지만 난 대부분 있도록, 또한 정규 표현식 라이브러리 쓸모 해요 효과적인 '그룹 찾기, 그룹 저장, 문자열에서 그룹 삭제'검색 중 '또한 크게 환영받을 것입니다.

답변

2

, 당신은 Match ES 당신의 패턴이 하나의 그룹이로 끝나지 Group의 전체를 반복하고 싶습니다. 이 작업을 수행하는 일반적인 방법은 그러나, 최강의 문제를 해결하기 위해 개별적으로 모든 데이터를 받고 다시 함께 문자열을 넣는 것은 약간 성가신 수 있습니다 마이클 군터의 for 루프 또는 단순히

Match m = reg.Match(line); 
while(m.Success) 
{ 
    // read class from m.Groups[1] 
    m = m.NextMatch(); 
} 

중 하나입니다 - 특히 경우 한 번에 여러 줄에서이 대체 작업을 수행하려고합니다.

따라서 Regex.Replace (콜백을받는 버전)을 살펴볼 수 있습니다. 그렇게하면 모든 항목을 단일 일치 항목과 일치시킬 수 있고 .NET의 고유 한 기능을 사용하여 단일 그룹의 여러 캡처에 액세스 할 수 있습니다.

클래스의
var line = "<!C43!><!TG!>Some Characters"; 

MatchEvaluator evaluator = new MatchEvaluator(ReplaceCallback); 

string output = Regex.Replace(
    line, 
    @"(?:<!([^<>]+)!>)+(.+)", 
    evaluator 
); 

그리고 다른 곳에서 : 문자열을 설정

static string ReplaceCallback(Match match) 
{ 
    var sb = new StringBuilder("<span class=\""); 
    sb.Append(match.Groups[1].Captures[0].Value); 
    for(int i = 1; i < match.Groups[1].Captures.Count; i++) 
    { 
     sb.Append(" "); 
     sb.Append(match.Groups[1].Captures[i].Value); 
    } 
    sb.Append("\">"); 
    sb.Append(match.Groups[2].Value); 
    sb.Append("</span>"); 
    return sb.ToString(); 
} 

아마 String.Format에 쉽게하지만 String.JoinCaptureCollection의 순간에 수있는 방법을 찾을 수 없습니다.

그래서이 기본적으로 무엇을하고 있는지 :

패턴 @"(?:<!([^<>]+)!>)+(.+)"은 하나 이상의 <!...!> "토큰"와 라인의 나머지 부분과 일치합니다. 그렇게하는 동안 <!...!>의 내용을 캡처합니다. 반복 할 때마다 다른 캡처가 기록되며 나중에 콜백에서 모두 캡처 할 수 있습니다. <!...!> 토큰이 끝나면 (.+)으로 나머지 줄을 캡처하고 캡처합니다. 문자열 앞에서 @을 확인하십시오. 정규식 패턴을 지정할 때 항상 수행해야하는 문자열을 축 어적으로 만듭니다. 그렇지 않으면 이스케이프 할 때 문제가 발생합니다. 첫 번째 여는 괄호 뒤에 ?:에 유의하십시오. 이는 구분 기호 <!!>을 포함하는 다른 캡처가 필요 없기 때문에 캡처를 억제하기위한 것입니다. 캡처를 실제로 필요로하지 않는 한 항상 캡처 링하지 않는 그룹을 사용하는 것도 좋은 습관입니다.

콜백 함수는 입력에서 매치마다 호출됩니다. 전체 행을 포함하는 일치 항목은 하나뿐입니다. 그 경기는 그룹 1과 그룹 2의 나머지 두 개의 토큰을 점령했습니다.

그래서 우리는 이제 단순히 <span ="로 시작하는 문자열, 다음 그룹 1, "> 라인의 다음 캡처 한 나머지 마지막으로 폐쇄 </span>의 모든 캡처의 다음 공백으로 구분 된 목록을 구축 할 수 있습니다.

내가 말했듯이 String.Join 콜렉션 그룹으로가는 길을 찾으면 콜백 함수가 세 줄 정도 줄어든다.

Match, GroupCapture의 차이는 여전히 당신에게 약간 퍼지 경우

, 나는 콜백 함수에 중단 점을 설정하고 단지 거기 match 개체를 검사하는 것이 좋습니다.

+0

와우, 완벽한 대답, 당신의 코드는 대접처럼 일했습니다! 고맙습니다! :-) – Nnoel

0

나는 RegexHero에 문제를 재현 할 수 없습니다

http://www.regexhero.net/tester

그것은으로 두 그룹을 캡처 :

1: C43 
1: TG 

가 확실 귀하의 의견은 당신이 될 것을 기대되고 있습니까? 결과에 대한 의도 된 컬렉션을 반복하고 있습니까?

+0

http://regexpal.com/ 내 정규 표현은 괜찮 ㄴ다고하지만 C#의 특정 문제는 무엇입니까? – Nnoel

+0

오 ... 이제 귀하의 링크가 실버 라이트 설치를 요청하고 있습니다 ... 나는 그것을 확인해 보겠습니다. – Nnoel

+0

나는 당신의 코드와 관련이 있다고 말할 것입니다. reg.Match 응답을 디버그하고 속성 등을 검사하십시오. – Haney

3

잘못된 일을 반복하고 있습니다. 이 시도 : 다른 사람의 말처럼

string line = ...; 
Regex reg = ...; 
for (var match = reg.Match(line); match.Success; match = match.NextMatch()) 
{ 
    // in here, don't bother with .Groups... you don't need it 
} 
+0

감사합니다. Micheal,이 대신 시도한 때 작동했습니다. – Nnoel