2012-08-02 4 views
3

정규식에 대해 배우려고합니다. 여기
내가 일치거야 무엇 :정규 표현식 : 쿼리 문자열 매개 변수 일치

/parent/child 
/parent/child? 
/parent/child?firstparam=abc123 
/parent/child?secondparam=def456 
/parent/child?firstparam=abc123&secondparam=def456 
/parent/child?secondparam=def456&firstparam=abc123 
/parent/child?thirdparam=ghi789&secondparam=def456&firstparam=abc123 
/parent/child?secondparam=def456&firstparam=abc123&thirdparam=ghi789 
/parent/child?thirdparam=ghi789 
/parent/child/ 
/parent/child/? 
/parent/child/?firstparam=abc123 
/parent/child/?secondparam=def456 
/parent/child/?firstparam=abc123&secondparam=def456 
/parent/child/?secondparam=def456&firstparam=abc123 
/parent/child/?thirdparam=ghi789&secondparam=def456&firstparam=abc123 
/parent/child/?secondparam=def456&firstparam=abc123&thirdparam=ghi789 
/parent/child/?thirdparam=ghi789 

내 표현은 "횡령" 및 def456을 ABC123한다.
그리고 지금 내가 일치하지 않을거야 일에 대해 단지 예 ("물음표"가없는) :

^(?:/parent/child){1}(?:^(?:/\?|\?)+(?:firstparam=([^&]*)|secondparam=([^&]*)|[^&]*)?)? 

그러나 아무튼 :

/parent/child/firstparam=abc123&secondparam=def456 

를 글쎄, 난 다음 식을 내장 일하지 마라.
내가 잘못하고있는 것을 이해하도록 도와 줄 수 있습니까?
미리 감사드립니다.

1

UPDATE 확인은, I는 다른 시험을했다. 나는 이런 식으로 뭔가에 이전 버전을 해결하기 위해 노력하고있어 :

/parent/child(?:(?:\?|/\?)+(?:firstparam=([^&]*)|secondparam=([^&]*)|[^&]*)?)?$ 

내 아이디어를 설명하자
가/부모/자녀와 함께 시작해야합니다 : 그룹에 이어

/parent/child 

는 선택 사항입니다

(?: ...)? 

이전 옵션 그룹은?으로 시작해야합니다. 또는?

(?:\?|/\?)+ 

선택적 매개 변수 (지정된 매개 변수는 쿼리 문자열의 일부인 경우 내가 값을 잡아)

$ 

어떤 조언 라인

(?:firstparam=([^&]*)|secondparam=([^&]*)|[^&]*)? 

끝? 내 솔루션은 단지 정규 표현식을 기반으로해야합니다 2

UPDATE.

/parent/child(?:[?&/]*(?:firstparam=([^&]*)|secondparam=([^&]*)|[^&]*))*$ 

그리고 그것은 꽤 좋은 작동합니다 그냥 예를 들어, 나는 이전 한 다음를 썼다. 그러나 너무 다음과 같은 입력과 일치 :

/parent/child/firstparam=abc123&secondparam=def456 

어떻게 이전 문자열과 일치하지 하기 위해 표현을 수정할 수?

+0

가능한가요? 항상이 구조를 가지고 있습니까? – FailedDev

+0

@FailedDev 예, 그렇습니다. – NicolaBaldi

+0

@NicolaBaldi 내 대답을 참조하십시오. 이것에 정규 표현식을 사용하지 마십시오. 당신이 할 수있는 작업을 간단한 문자열 처리 함수로 해결할 수 있어야합니다.) 정규식은 값 비싼 도구입니다. – gaussblurinc

답변

2

언어를 지정하지 않았으므로 Perl을 사용하겠습니다. 그래서 기본적으로 모든 것을 매칭하는 대신에, 나는 당신이 필요하다고 생각했던 것과 정확히 일치했습니다. 내가 틀렸다면 나를 바로 잡으십시오.

while ($subject =~ m/(?<==)\w+?(?=&|\W|$)/g) { 
    # matched text = $& 
} 

(?<=  # Assert that the regex below can be matched, with the match ending at this position (positive lookbehind) 
    =  # Match the character “=” literally 
) 
\\w   # Match a single character that is a “word character” (letters, digits, and underscores) 
    +?  # Between one and unlimited times, as few times as possible, expanding as needed (lazy) 
(?=   # Assert that the regex below can be matched, starting at this position (positive lookahead) 
      # Match either the regular expression below (attempting the next alternative only if this one fails) 
     &  # Match the character “&” literally 
    |  # Or match regular expression number 2 below (attempting the next alternative only if this one fails) 
     \\W # Match a single character that is a “non-word character” 
    |  # Or match regular expression number 3 below (the entire group fails if this one fails to match) 
     \$ # Assert position at the end of the string (or before the line break at the end of the string, if any) 
) 

출력 :

Results

+0

감사합니다 FailedDev,하지만 .NET Framework의 regex 엔진을 사용하고 있습니다. Perl 구문이 나에게 명확하지 않습니다. :-( 어쨌든, 내 패턴에 문제가 있는지 궁금하다. – NicolaBaldi

+0

이 정규 표현식 구문이 lang에서 lang으로 변경 되었습니까? – mmdemirbas

+0

@ NicolaBaldi 정규 표현식 부분을 가져 와서 .net에 연결할 수 있습니다. – FailedDev

0

내 솔루션 :
/(?:\w+/)*(?:(?:\w+)?\?(?:\w+=\w+(?:&\w+=\w+)*)?|\w+|)

는 설명 :
/(?:\w+/)* 경기 /parent/child/ 또는 /parent/

(?:\w+)?\?(?:\w+=\w+(?:&\w+=\w+)*)? 경기 child?firstparam=abc123 또는 ?firstparam=abc123 또는 ?

\w+ 일치하는 텍스트 만 쿼리 문자열을해야하는 경우

는, 패턴 줄일 것 (빈) child

..|) 일치 아무것도 같은과 같은 :
/(?:\w+/)*(?:\w+)?\?(\w+=\w+(?:&\w+=\w+)*)

모든 매개 변수를 쿼리에서 가져 오려면 문자열,이 루비 샘플입니다 :

re = /\/(?:\w+\/)*(?:\w+)?\?(\w+=\w+(?:&\w+=\w+)*)/ 
s = '/parent/child?secondparam=def456&firstparam=abc123&thirdparam=ghi789' 
if m = s.match(re) 
    query_str = m[1] # now, you can 100% trust this string 
    query_str.scan(/(\w+)=(\w+)/) do |param,value| #grab parameter 
     printf("%s, %s\n", param, value) 
    end 
end 

출력

secondparam, def456 
firstparam, abc123 
thirdparam, ghi789 
+0

고맙습니다.귀하의 솔루션은 제게 많은 도움이되지만 여전히 너무 일반적이어서 매개 변수 값을 얻지 못합니다. 제발, 내 최근 업데이 트를 봐. – NicolaBaldi

+0

내 솔루션은 정규식을 기반으로해야합니다. Update 2를보십시오. 나는 거의 바른 길에 있다고 생각합니다 (희망!). – NicolaBaldi

0

당신은 선발을위한 정규식에 /의 탈출 무언가의 단일 반복에 대한 {1}를 사용하지 않는 불필요한입니다; 당신은 하나 이상의 반복 또는 반복의 범위를 원할 때만 그것들을 사용합니다.

그리고 당신이하려는 일 중 일부는 단순히 정규식을 사용하지 않는 것입니다. 좀 더 쉬운 방법을 보여 드리겠습니다 : 분할과 같은 것을 사용하고 나중에 내용을 확인할 수있는 해시에 정보를 넣고 싶습니다. 언어를 지정하지 않았기 때문에 필자는 Perl을 예제로 사용하려고합니다. 그러나 정규 표현식을 사용하여 알고있는 모든 언어에서도 해시 및 분할과 같은 쉬운 액세스가 가능하므로 이식하기가 쉬워야합니다.

# I picked an example to show how this works. 
my $route = '/parent/child/?first=123&second=345&third=678'; 
my %params; # I'm going to put those URL parameters in this hash. 

# Perl has a way to let me avoid escaping the /s, but I wanted an example that 
# works in other languages too. 
if ($route =~ m/\/parent\/child\/\?(.*)/) { # Use the regex for this part 
    print "Matched route.\n"; 
    # But NOT for this part. 
    my $query = $1; # $1 is a Perl thing. It contains what (.*) matched above. 
    my @items = split '&', $query; # Each item is something like param=123 
    foreach my $item (@items) { 
    my ($param, $value) = split '=', $item; 
    $params{$param} = $value; # Put the parameters in a hash for easy access. 
    print "$param set to $value \n"; 
    } 
} 

# Now you can check the parameter values and do whatever you need to with them. 
# And you can add new parameters whenever you want, etc. 
if ($params{'first'} eq '123') { 
    # Do whatever 
} 
0

이 스크립트를 사용하시면 도움이됩니다.
우선, 확인하십시오. ?과 같은 기호가 있는지 확인하십시오.
그런 다음 줄의 첫 번째 부분을 삭제합니다 (왼쪽에서 ?).
다음으로, 줄을 &으로 나눕니다. 각 값은 =으로 나뉩니다.

my $r = q"/parent/child 
/parent/child? 
/parent/child?firstparam=abc123 
/parent/child?secondparam=def456 
/parent/child?firstparam=abc123&secondparam=def456 
/parent/child?secondparam=def456&firstparam=abc123 
/parent/child?thirdparam=ghi789&secondparam=def456&firstparam=abc123 
/parent/child?secondparam=def456&firstparam=abc123&thirdparam=ghi789 
/parent/child?thirdparam=ghi789 
/parent/child/ 
/parent/child/? 
/parent/child/?firstparam=abc123 
/parent/child/?secondparam=def456 
/parent/child/?firstparam=abc123&secondparam=def456 
/parent/child/?secondparam=def456&firstparam=abc123 
/parent/child/?thirdparam=ghi789&secondparam=def456&firstparam=abc123 
/parent/child/?secondparam=def456&firstparam=abc123&thirdparam=ghi789 
/parent/child/?thirdparam=ghi789"; 


for my $string(split /\n/, $r){ 
     if (index($string,'?')!=-1){ 
      substr($string, 0, index($string,'?')+1,""); 
      #say "string = ".$string; 
      if (index($string,'=')!=-1){ 
       my @params = map{$_ = [split /=/, $_];}split/\&/, $string; 
       $"="\n"; 
       say "$_->[0] === $_->[1]" for (@params); 
       say "######next########"; 
       } 
      else{ 
       #print "there is no params!" 
      }  

     } 
     else{ 
      #say "there is no params!"; 
     }  
    } 
1

이 정규식은 매개 변수 이름이 무엇인지 알면 변경되지 않습니다.

\/parent\/child\/?\?(?:(?:firstparam|secondparam|thirdparam)\=([\w]+)&?)(?:(?:firstparam|secondparam|thirdparam)\=([\w]+)&?)?(?:(?:firstparam|secondparam|thirdparam)\=([\w]+)&?)? 

정규식 당신이 최대로 정규식 솔루션을 필요로하는 경우이 작동합니다 (문자열 함수는 정규 표현식에 비해 빠른 방법이기 때문에 위의 코드 예제는 까지 더 효율적으로 될 것입니다)이 최상의 솔루션이 아닌 동안 3 매개 변수. 관심 밖에서 왜 솔루션은 정규식만을 사용해야합니까?

/parent/child?firstparam=abc123 
/parent/child?secondparam=def456 
/parent/child?firstparam=abc123&secondparam=def456 
/parent/child?secondparam=def456&firstparam=abc123 
/parent/child?thirdparam=ghi789&secondparam=def456&firstparam=abc123 
/parent/child?secondparam=def456&firstparam=abc123&thirdparam=ghi789 
/parent/child?thirdparam=ghi789 
/parent/child/?firstparam=abc123 
/parent/child/?secondparam=def456 
/parent/child/?firstparam=abc123&secondparam=def456 
/parent/child/?secondparam=def456&firstparam=abc123 
/parent/child/?thirdparam=ghi789&secondparam=def456&firstparam=abc123 
/parent/child/?secondparam=def456&firstparam=abc123&thirdparam=ghi789 
/parent/child/?thirdparam=ghi789 

그것은 지금 만 포함 된 쿼리 문자열 매개 변수와 일치하는 것이며, 당신을 위해 캡처 그룹으로 넣어 :

어떤 경우에는,이 정규식은 다음 문자열과 일치합니다.

성냥을 처리하는 데 사용하는 언어는 무엇입니까? 당신이 PHP로 preg_match를 사용하는 경우

, 당신은 그럼 당신은 $ 일치를 [0]와 나머지 전체 경기에 액세스 할 수 있습니다

preg_match($regex, $string, $matches); 

으로 배열 전체 경기뿐만 아니라 캡처 그룹을 얻을 수 있습니다 $ matches [1], $ matches [2] 등을 사용합니다.

매개 변수를 추가하려면 정규식에 매개 변수를 추가하고 데이터를 얻기 위해 추가 부품을 추가해야합니다. 예를 들어, 경우

/parent/child/?secondparam=def456&firstparam=abc123&fourthparam=jkl01112&thirdparam=ghi789 

했다 정규식은

\/parent\/child\/?\?(?:(?:firstparam|secondparam|thirdparam|fourthparam)\=([\w]+)&?)(?:(?:firstparam|secondparam|thirdparam|fourthparam)\=([\w]+)&?)?(?:(?:firstparam|secondparam|thirdparam|fourthparam)\=([\w]+)&?)?(?:(?:firstparam|secondparam|thirdparam|fourthparam)\=([\w]+)&?)? 

이 그래도 좀 더 지루한 더 많은 매개 변수를 추가로 유지하기 될 것입니다 될 것입니다.

멀티 라인 플래그가 활성화되어 있으면 시작과 끝 부분에 선택적으로^$를 포함 할 수 있습니다. 당신은 또한 쿼리 문자열없이 전체 라인을 일치해야하는 경우 (^ $ 포함) 비 캡처 그룹이 모든 정규식을 감싸고 끝까지

|(?:^\/parent\/child\/?\??$) 

를 추가합니다.