2010-01-01 2 views
0

유효성을 검사 할 텍스트 문자열은 "세그먼트"라고합니다. Regex 도움말 : 정규식 패턴이 잘못된 문자열과 일치합니다

[A-Z,S,3] 

지금까지 내가 작동이 정규식 패턴

(?:\[(?<segment>[^,\]\[}' ]+?,[S|D],\d{1})\])+? 

를 구축하는 데 성공하지만 전체 텍스트 문자열이 잘못 텍스트를 포함하더라도 그것은 일치하는 항목을 반환합니다 하나의 세그먼트는 다음과 같을 수 있습니다. 나는 ^$ 어딘가에 내 패턴을 사용해야한다고 생각하지만 어떻게 될지 모르겠다!?

내 패턴은 다음과 같은 결과 생산하고자하는

:

  • [A-Z,S,3][A-Za-z0-9åäöÅÄÖ,D,4]OK (두 개의 세그먼트)
  • [A-Z,S,3]aaaa[A-Za-z0-9åäöÅÄÖ,D,4]일치를
  • crap[A-Z,S,3][A-Za-z0-9åäöÅÄÖ,D,4]일치
  • [A-Z,S,3][]일치하지 않음
  • [A-Z,S,3][klm,D,4][0-9,S,1]OK (3 개 개의 세그먼트)
+1

어떤 언어를 사용하고 있습니까? –

+0

C# (최신 .Net 3.5). 또한 성공한 일치를 얻으면 (가능한 경우) "세그먼트"를 추출하고 싶습니다. 아마도 내가 할 두 번째 패턴이 필요할까요? – David

답변

3

^을 사용하여 시작을 고정하고 $를 사용하여 끝을 고정합니다. 예 : ^(abc)*$, 그룹의 반복 횟수 (이 예에서는 "abc")와 일치하며 입력 문자열의 시작에서 시작하여 끝에서 끝나야합니다.

— ungreedy를 사용하여 +?은 중요하지 않습니다. 어쨌든 끝까지 일치해야합니다. 그러나 정규식에는 몇 가지 문제가 있습니다.

^(?:\[[^,]+,[SD],\d\])+$ —는 사용자가 원하는 것과 유사합니다.

    난 당신이 내 정규식이 요구되는 것보다 더 일반적인 그래서, 첫 번째 부분 무슨 뜻인지 해독 할 수
  • , [^,]+,는 쉼표가 아닌 쉼표의 순서와 일치합니다, 사실 당신은 아마 ]를 추가해야 이 부정 문자 클래스. |는 (비록 [SD]과 같은 의미 (S|D)) 여기 교대를 의미하지 않는
  • [S|D]
  • 문자의 문자 클래스입니다.
  • {1}이 모든 원자의 기본값이므로 지정할 필요가 없습니다.

Pseudocode (codepad.org에서 실행) :

import re 
def find_segments(input_string): 
    results = [] 
    regex = re.compile(r"\[([^],]+),([SD]),(\d)\]") 
    start = 0 
    while True: 
    m = regex.match(input_string, start) 
    if not m: # no match 
     return None # whole string didn't match, do another action as appropriate 
    results.append(m.group(1, 2, 3)) 
    start = m.end(0) 
    if start == len(input_string): 
     break 
    return results 

print find_segments("[A-Z,S,3][klm,D,4][0-9,S,1]") 
# output: 
#[('A-Z', 'S', '3'), ('klm', 'D', '4'), ('0-9', 'S', '1')] 

여기에 큰 차이는 표현은 전체 [...] 부분 일치이지만 연속적으로 적용되는, 그래서 그들은 다시 시작해야합니다 마지막 부분은 끝납니다 (또는 문자열의 끝에서 끝납니다).

+0

감사! 내 질문에 대한 훌륭한 대답. 것은 "세그먼트"를 추출하고 싶습니다. 매치 컬렉션 또는 그룹 중 하나입니다. 내 원래 패턴을 보면, 먼저 비 포획 그룹이 있고, 그 다음에 캡처 그룹이 "세그먼트"를 추출한다는 것을 알 수 있습니다. 그것을 당신의 패턴에 통합시키는 것이 가능한가? – David

+0

네, 똑같은 방식으로, 당신이 관심있는 것에 대해 캡쳐 그룹을 추가하십시오. 그러나 첫 번째 또는 두 번째 함수 대신에 모든 함수를 포착하려면 정규식 라이브러리를 다른 함수로 호출해야 할 수 있습니다. 마지막으로 캡처 그룹이 대신 반복됩니다. 나는 예제로 업데이트 할 것이다. –

+0

+1 : 그건 파이썬으로 해결하는 좋은 방법입니다. 두 개의 거의 동일한 정규 표현식을 사용하면 동일한 문자열에 대해 두 번 일치하는 성능이 저하됩니다. 하지만 .NET의 Regex는 어떤 부분이 파이썬처럼 시작되어야하는지 또는 문자열을 복사하여 성능 이점을 무효로 할 것인지를 말하기위한 옵션이 있습니까? –

0

당신이 뭔가 싶어 :

using System; 
using System.Text.RegularExpressions; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     string[] tests = { 
      "[A-Z,S,3][A-Za-z0-9,D,4]", 
      "[A-Z,S,3]aaaa[A-Za-z0-9,D,4]", 
      "crap[A-Z,S,3][A-Za-z0-9,D,4]", 
      "[A-Z,S,3][]", 
      "[A-Z,S,3][klm,D,4][0-9,S,1]" 
     }; 

     string segmentRegex = @"\[([^],]+,[SD],\d)\]"; 
     string lineRegex = "^(" + segmentRegex + ")+$"; 

     foreach (string test in tests) 
     { 
      bool isMatch = Regex.Match(test, lineRegex).Success; 
      if (isMatch) 
      { 
       Console.WriteLine("Successful match: " + test); 
       foreach (Match match in Regex.Matches(test, segmentRegex)) 
       { 
        Console.WriteLine(match.Groups[1]); 
       } 
      } 
     } 
    } 
} 
: 여기

/^(\[[^],]+,[SD],\d\])+$/ 

는 C#에서이 정규 표현식을 사용할 수있는 방법의 예입니다

출력 :

Successful match: [A-Z,S,3][A-Za-z0-9,D,4] 
A-Z,S,3 
A-Za-z0-9,D,4 
Successful match: [A-Z,S,3][klm,D,4][0-9,S,1] 
A-Z,S,3 
klm,D,4 
0-9,S,1 
관련 문제