2013-09-24 11 views
6

오늘 나는 다음과 같은 정규 표현식을 가로 질러왔다 정규 표현식에 한정 기호로 사용 루비 그것으로 어떻게 할 것인지 알고 싶어 할 때 :의미`+`이어`*`, 후자는

> "#a" =~ /^[\W].*+$/ 
=> 0 
> "1a" =~ /^[\W].*+$/ 
=> nil 

이 경우 Ruby는 + 문자를 무시하는 것으로 보입니다. 그게 잘못되면, 나는 그것으로 무엇을하고 있는지 잘 모르겠습니다. *이 이스케이프되지 않고 한정 기호로 사용되기 때문에 한정 기호로 해석되지 않는 것으로 추측됩니다. Perl/Ruby 정규 표현식에서 특수 문자로 해석 될 수없는 문맥에서 문자 (예 : -)가 사용되는 경우 리터럴로 취급됩니다. 그러나이 경우에 그런 일이 발생하면 lvalue 문자열에 +이 없으므로 첫 번째 일치가 실패 할 것으로 예상됩니다.

+ 문자를 사용하는 것이 적절합니까? 위의 동작이 버그입니까? 나는 명백한 것을 놓치고 있는가?

+0

어디에서이 정규식을 발견 했습니까? –

+0

내 작업 과정에서 일부 타사 보안 내용이 있습니다. 저는 정규 표현식이 저자가 의도 한 것과 다르다고 생각 합니다만, 루비의 행동을 보았을 때 나는이 가정에 대해 질문하기 시작했습니다. –

답변

5

글쎄, * 뒤에 확실히 +을 사용할 수 있습니다. 그것에 대해 조금 읽을 수 있습니다 on this site. * 뒤에있는 +은 소유량 한정 기호라고합니다.

그것은 무엇입니까? *의 역 추적을 방지합니다.

당신이 .*c 같은과 abcde에 맞게이를 이용이있을 때 일반적으로,의 .* 먼저 전체 문자열 (abcde)와 일치되고 .*c 일치하지 않을 수 정규식 때문에, 엔진은 다시 한 문자 이동합니다 경기가 있는지 확인하는 시간입니다 (역 추적).

c으로 역 추적하면 abcabcde에서 나타납니다.

지금은 엔진이 몇 백 문자를 역 추적하는 상상, 그리고 당신이 그룹을 중첩하고 * (또는 + 또는 {m,n} 양식) 여러 경우, 신속 수천 끝낼 수, 문자의 수백만, 역 추적하기 catastrophic backtracking이라고합니다.

여기에서 소유량 한정 기호가 유용합니다. 그들은 실제로 어떤 형태의 후퇴를 막습니다. 위에서 언급 한 정규 표현식에서 abcde.*+c과 일치하지 않습니다. .*+이 전체 문자열을 소비 한 후에는 역 추적 할 수 없으며 문자열 끝에 c이 없으므로 일치하지 않습니다.

따라서 소유량 한정 기호의 또 다른 가능한 사용법은 엔진이 지원할 수있는 경우 일부 정규식의 성능을 향상시킬 수 있다는 것입니다.

정규식이 /^[\W].*+$/인데, 소유량 한정 기호가 제공하는 개선 (어쩌면 작은 개선)이 있다고 생각하지 않습니다. 그리고 마지막으로 /^\W.*+$/으로 쉽게 다시 쓸 수 있습니다.

+0

당신이 얻을 수있는 유일한 개선점은 엔진이'. *'와 일치하는 동안 중간 상태를 저장할 필요가 없다는 것입니다 (나중에 * 되돌리기 위해 * 사용됩니다).그러나 그 패턴은 어쨌든 결코 되돌아 가지 않을 것이므로 그 목적을위한 절약은 없습니다. –

+0

뛰어난 글쓰기 - 고맙습니다. –

+0

@EricWalker 환영합니다 :) – Jerry