문제
나는 읽고 있었다 이 질문 웹페이지에서 URL을 구문 분석하는 방법에 대해 질문했고 수락된 답변 이 솔루션을 제공했습니다.
((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+)
솔루션은 다음에서 제공되었습니다. csmba 그리고 그는 그것을 인정했다 regexlib.com.아휴.크레딧이 완료되었습니다.
나는 이것이 상당히 순진한 정규식이라고 생각하지만 더 나은 것을 구축하기 위한 좋은 출발점이 됩니다.하지만 내 질문은 이렇습니다.
요점은 무엇입니까 {1}
?"정확히 이전 그룹 중 하나"라는 뜻이죠?이것이 정규식에서 그룹화의 기본 동작이 아닌가요?만약 그렇다면 표현이 어떻게든 바뀌겠는가? {1}
제거됐나요?
동료에게서 이것을 본다면 나는 그 사람의 오류를 지적하겠지만 내가 이 글을 쓰는 동안 응답은 6점으로 평가되었고 regexlib.com의 표현은 5점 만점에 4점으로 평가되었습니다.어쩌면 제가 뭔가를 놓치고 있는 게 아닐까요?
해결책
@Jeff Atwood, 해석이 약간 다릅니다. {1}은 정확히 한 번 일치한다는 의미이지만 "캡처"에는 영향을 미치지 않습니다. 캡처는 괄호로 인해 발생합니다. 중괄호는 패턴이 일치해야 하는 횟수만 지정합니다. 출처-당신이 말한대로 한 번.
나는 @Marius의 답변에 동의합니다. 비록 그의 대답이 약간 간결하고 경솔한 것처럼 보일 수도 있습니다.정규식을 사용하는 데 익숙하지 않은 경우 정규식은 어렵고 질문의 {1}은 오류가 아닙니다. 이를 지원하는 시스템에서는 "정확히 하나의 일치"를 의미합니다.이런 의미에서 실제로는 아무 것도 수행하지 않습니다.
불행하게도 현재 삭제된 게시물과는 달리 정규식 일치를 유지하지는 않습니다. http://http://example.org
, 끝에 있는 \S+는 다음을 포함하여 하나 이상의 공백이 아닌 문자와 일치하기 때문입니다. http://example.org
~에 http://http://example.org
(정규 표현식 읽기가 꺼져 있는 경우를 대비해 Python 2.5를 사용하여 확인했습니다.)따라서 주어진 정규 표현식은 실제로 최고가 아닙니다.나는 URL 전문가는 아니지만, 좋은 URL을 보장하려면 첫 번째 항목 이후 ":" 및 "//"의 표시를 제한하는 것이 필요할 것입니다(그러나 충분하지는 않습니다).
다른 팁
@롭:나는 동의하지 않습니다.귀하가 요청한 내용을 시행하려면 가능하지만 확실히 {1} 사용과 관련이 없는 부정적인 뒤돌아보기를 사용해야 한다고 생각합니다.어느 버전의 정규 표현식도 특정 문제를 해결하지 않습니다.
코드가 말하도록 하려면:
tibook 0 /home/jj33/swap > cat text
Text this is http://example.com text this is
Text this is http://http://example.com text this is
tibook 0 /home/jj33/swap > cat p
#!/usr/bin/perl
my $re1 = '((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+)';
my $re2 = '((mailto\:|(news|(ht|f)tp(s?))\://)\S+)';
while (<>) {
print "Evaluating: $_";
print "re1 saw \$1 = $1\n" if (/$re1/);
print "re2 saw \$1 = $1\n" if (/$re2/);
}
tibook 0 /home/jj33/swap > cat text | perl p
Evaluating: Text this is http://example.com text this is
re1 saw $1 = http://example.com
re2 saw $1 = http://example.com
Evaluating: Text this is http://http://example.com text this is
re1 saw $1 = http://http://example.com
re2 saw $1 = http://http://example.com
tibook 0 /home/jj33/swap >
따라서 두 버전 사이에 차이가 있다면 귀하가 제안한 버전은 아닌 것 같습니다.
해당 정규식에 {1}에 유효한 함수가 없는 것 같습니다.
(**mailto:|(뉴스|(ht|f)tp(s?))://){1}**
이것을 다음과 같이 읽어야 합니다:"정확히 한 번만 괄호 안의 내용을 캡처합니다."그러나 우리는 나중에 사용하기 위해 이것을 캡처하는 것에 대해 별로 신경 쓰지 않습니다(예: 교체 비용 1달러).그래서 그것은 무의미합니다.
제 생각에는 아무런 목적도 없다고 생각합니다.그러나 RegEx는 이해/분해가 거의 불가능하기 때문에 사람들은 오류를 거의 지적하지 않습니다.아마 그래서 아무도 지적하지 않았을 겁니다.