2011-08-09 3 views
1

다음은 PHP 또는 JavaScript 소스 코드 (this post)의 문자열을 일치시키기위한 PHP 정규 표현식입니다.하지만 문제가 있다고 생각됩니다. 리터럴 파이썬 (또는 그렇지 않은 경우 PERL)은 무엇입니까?이 PHP 정규 표현식의 목적을 Python/PERL로 번역

~'(\\.|[^'])*'|"(\\.|[^"])*"~s 
  • s modifier는 점은 줄 바꿈을 포함한 모든 문자를 일치 의미; 파이썬에서 그게 re.compile(..., re.DOTALL)
  • 나는 완전히 \\.의 의도를 얻지 못합니까? 그게 .으로 줄어들습니까? 이중 백 슬래시는 PHP에서 두 번 이스케이프 처리해야합니까? \\. 또는 [^'] (비 - 인용 자) 중 하나의 일치 의 모든 위치를 수
  • 이 사람의 정규식이 불면 왜 어쩌면 설명하고, 나에게 총 과잉을 보인다. [^'] 그룹이 s 수정자를 사용하는 .에있는 모든 항목과 일치하지는 않으므로 반드시 일치해야합니다. 파이썬에서, 싱글, 큰 따옴표로 정규식의 두 가지 버전을 구성하는

  • 이 정규식의 간단한 버전이 list of PHP regex examples, under Programming: String에서 찾을 수 있습니다 this two-step approach

  • NB를 사용할 수 있습니다.

+0

나는 단지 질문을 다시 읽고 지금 혼란 스럽다. 그 다른 스레드에서 당신은 시스템이 정지되거나 충돌 할 수있는 정규 표현식을 찾고 있었고,이 정규식은 답변 중 하나였습니다. 이 시간이 지나면 너 뭐야? 정규식을 향상 시키길 원하십니까? 아니면 PHP에서와 같이 파이썬에서 문제가 발생했는지 알고 싶습니까? –

+0

@Alan,이 질문은 정확히 말합니다 :이 사람의 PHP 정규 표현식의 의도, 즉 정확히이 정규 표현식이 일치하는 여러 줄의 문자열을 설명하십시오. 그게 다야. – smci

답변

1

정규식은 탈출 따옴표 (즉, \"\')를 처리하지 않습니다 제외하고, 대부분 괜찮습니다. 수정하기가 쉽습니다.

'(?:\\.|[^'\\]+)*'|"(?:\\.|[^"\\]+)*" 

"일반"정규식입니다. 현 재 대부분의

'~\'(?:\\\\.|[^\'\\\\]+)*\'|"(?:\\\\.|[^"\\\\]+)*"~s' 

: PHP에서

r"""'(?:\\.|[^'\\]+)*'|"(?:\\.|[^"\\]+)*"""" 

당신이 PHP의 문자열 처리 과거를 얻을 수있는 백 슬래시를 탈출해야 : 파이썬에서 당신은 일반적으로 원시 문자열의 형태를 작성합니다 인기있는 언어는 이스케이프가 덜 필요한 문자열 유형이거나 정규식 리터럴을 지원하거나 둘 다 있습니다.여기에 귀하의 정규식 C#을 그대로 문자열로 보일 것이다 방법은 다음과 같습니다 따로 고려를 포맷,

@"'(?:\\.|[^'\\]+)*'|""(?:\\.|[^""\\]+)*""" 

을하지만, 그 자체가 (뿐만 아니라 다른 많은 맛) 어떤 펄 파생 맛에서 작동해야 정규식.


p.s : 문자 클래스에 + 한정 기호를 어떻게 추가했는지 유의하십시오. 한 번에 한 성격과 일치하는 것에 대한 당신의 직감은 정확합니다. +을 추가하면 이 큰 차이가납니다. 성능 차이가입니다. 그러나 그것이 당신을 속일 수는 없습니다. 당신이 정규 표현식을 다룰 때, 직감은 틀린 것처럼 보입니다. :/

+0

원래의 정규 표현식은 이스케이프 된 따옴표를 처리합니다.'\\.'는'[^ ']'앞에 일치하므로 잘 작동합니다. '+'를 덧붙여서 성능을 향상시키는 것에 대한 당신의 요지는 유효하지만, 문자 클래스의 백 슬래시도 제외해야합니다. –

+0

@Long Ears : 올바른 형식의 문자열 리터럴에서는 괜찮지 만,' "\"와 같이해서는 안되는 것과 일치합니다. 처음에'\\.'대안은'\ "'와 일치하지만, 마지막'''은 아무것도 매치하지 않습니다. 그래서 그것은 뒤로 물러나서'[^.]'대안을 대신 백 슬래시와 일치시키고, Bob은 당신의 삼촌을 찾습니다! –

+0

음, 잘못된 형식의 소스 코드를 고려한다면 간단한 정규식이 아닌 전체 렉서를 사용해야합니다. 성냥이 없다는 것은 정확함을 의미하지는 않습니다.) –

2

\\.는 패턴 리터럴 백 슬래시를 일치하고 다음 캐릭터를 소화하기위한 것입니다. PHP (및 Python)의 패턴은 문자열에 포함되어 있으므로 문자열에 실제로 \\\\.이 있어야하므로 정규 표현식에서 \\.으로 끝납니다.

다음 문자를 매치하는 것이 중요합니다. 그렇지 않으면 일치를 조기에 끝낼 수있는 따옴표를 이스케이프하는 데 사용할 수 있기 때문에 다음 문자를 삼키는 것이 중요합니다.

이 패턴은 정상적으로 작동하는 것처럼 보입니다.이 패턴을 표현하는보다 간결한 방법을 생각할 수 없습니다.

또한 파이썬에서는 잘 작동해야합니다 (말한 것처럼 re.DOTALL). 파이썬에서는 여전히 작은 따옴표를 이스케이프해야하지만 원시 문자열 표기법을 사용하여 백 슬래시의 추가 이스케이프를 절약 할 수 있습니다. 이 동일해야 :

re.search(r'\'(\\.|[^\'])*\'|"(\\.|[^"])*"', str, re.DOTALL)

관련 문제