2013-08-07 3 views
6

요청 추적기 4.0에서 일부 Perl 코드를 사용하여 티켓 요청자의 메시지가 잘리는 오류가 발생했습니다. 필자는 Perl을 처음 사용하기 때문에 정규 표현식으로 몇 가지 작업을 수행했지만 꽤 많이 읽은 후에도이 문제에 약간의 문제가 있습니다.

나는이 코드 줄 아래로 내 문제를 좁혀 : 나는 완전히이 무엇을하고 있는지 이해하지 않고 더 나은 설명을 부탁합니다

$content =~ s/\n-- \n.*?$//s 

.

나는 s/ /\n-- \n.*?$ 패턴과 일치하고 아무것도없는 것으로 알고 있습니다.

무엇이 .*?$을 이해하지 못합니다.

  • .
  • *
  • ?
  • $가 선행 문자의 0 또는 1 배 선행 문자의 0 번 이상 어떤 \를 제외한 문자 N
  • 입니다 : 여기 내 기본적인 이해입니다 문자열의 끝

그렇다면 내가 알기로 최종 s. 일치하는 새 줄

따라서 대충, 우리는 \n-- \n으로 시작하는 모든 텍스트를 대체합니다.이 코드는 누군가가 여기에서 무슨 일이 일어나는지 설명 할 수 있다면 내가 정리하고 싶어하는 의심스러운 행동을 일으키고 있습니다.

누군가이 행의 기능을 설명 할 수 있습니까? 첫 번째 문자 인 \n-- \n 이후의 모든 텍스트가 삭제되었거나 더 많습니까?

긴 숨이 찬 부품/실제 문제

내 정확한 문제는 서명에서 인용 한 내용을 절단이다 (당신은 질문에 대답하기 위해이 글을 읽을 필요가 없습니다).

그래서 고객의 이메일 (A)는 말한다면 :

은 무엇을 위해 ABCD와 함께 일이야?
- 일부 고객 직원의 응답이 말한다

순서 ABCD와 무슨 일

그것은 출하 오늘

(고객의 서명의 손실을주의)?

고객은

나는 그것을하지 않았다,는 제공되지 않았다 응답!
- 일부 고객

그것은 출하 오늘

무엇을 위해 ABCD와 함께 일이야? 모든 상황을 죽이고 - 우리가 회신 할 때

, 그들의 메시지에서 차단됩니다.

그것은 내가이 제공되지 않았다 그것을하지 않았다 번호 12345

추적, 오늘 출하!

그리고 당신은 거의 정확한하는지 등 그것이 순서,

답변

8

설명 더 많은 작업에 이르게 : 그것은 끝에 "\ N-- \ n"의 마지막 발생에 이르기까지 모든 것을 제거 . 이것이 첫 번째 발생에서 모든 것을 제거하지 않는다는 것은 non-greedyness 연산자 ?에 의한 것입니다. 정규 표현식 엔진이 선행 패턴 (.*)의 가장 짧은 포스트 스크립트 형식과 일치하도록 지시합니다.

내용 : 전자 메일 통신에서 서명은 대개 두 개의 대시와 한 개의 후미 공백으로 구성된 줄과 정확히 같은 본 패턴으로 메시지 본문과 구분됩니다. 그러므로 정규 표현식이하는 일은 서명 구분 기호로 시작하는 모든 것을 끝까지 제거하는 것입니다.

이제 고객이 (수동 또는 이메일 클라이언트를 통해) 수행 한 작업은 서명 구분 기호 다음에 이메일의 답장을 추가하는 것입니다. 이것은 매우 드문 경우입니다. 인용 된 응답은 서명 한정자 앞에 있어야합니다. 나는 이것을 목적으로하는 하나의 이메일 클라이언트에 대해 모른다. 그러나 슬프게도 거기에는 많은 이메일이있다. (SMTP가 아닌 charset 문제에서 엄청난 실수를 범할 수있다.) , 나는 참으로 그러한 고객이 있음을 알면 놀라지 않을 것입니다.

또 다른 가능성은 -- 다음에 자신의 이름에 서명하는 것과 같은 클라이언트의 영향입니다. 그러나, 인간이 2 줄의 대시와 줄 바꿈 뒤에 후행 공백을 삽입하는 경우는 드물기 때문에 수동으로 수행 한 것은 아닙니다. ?이 한정사를 (?, *, + 또는 {m,n}) 다음

+1

썬더 버드는 적어도 그 옵션을 제공합니다. 따옴표를 서명 위나 아래에 둘지 여부를 선택할 수 있습니다. 회신 할 때 '- \ n'부분을 자르면 충분히 똑똑하지만 자체 따옴표도 자릅니다. Outlook에서는 구분 기호를 전혀 신경 쓰지 않고 항상 구분 기호를 서명 아래에 넣습니다 (구분 기호를 직접 입력해야합니다). TheBat에서! 템플릿에 원하는 곳에 따옴표를 넣습니다. – simbabque

2

는, 그 한정사 [1]의 탐욕을 수정한다. 일반적으로 이러한 한정 기호는 가능한 한 대부분의 문자와 일치하지만, ?은 가장 적은 문자와 일치합니다.

say "Greedy:  ", "abc1234" =~ /\w(.*)\d/; 
say "Non-greedy: ", "abc1234" =~ /\w(.*?)\d/; 

출력 :

bc123 
bc 

가 이후 $, 이것은 다음과 같은 효과가있다 (후행 줄 바꿈 전이나 문자열의 끝에서) 일치 할 수있는 두 장소 :

$_ = "abc\n-- \ndef\n"; 
say "Greedy:  <<" . s/\n-- \n.*$//sr . ">>"; 
say "Non-greedy: <<" . s/\n-- \n.*?$//sr . ">>"; 

을 출력 :

Greedy:  <<abc>> 
Non-greedy: <<abc 
>> 

마지막 행을 종료하는 개행이 제거되지 않도록합니다. 다음은 더 간단 등가물 : 그것은 처음 -- 시작으로 삭제됩니다

s/\n-- \n.*/\n/s 

s/(?<=\n)-- \n.*//s # Slow 

s/\n\K-- \n.*//s  # Requires 5.10 

참고. 마지막에서 제거를 시작하려면

$ perl -E'say "abc\n-- \ndef\n-- \nghi\n" =~ s/\n-- \n.*?$//sr' 
abc 

, 당신은 -- 일치하지 않는 것이 보증 뭔가 .*를 교체해야합니다.

$ perl -E'say "abc\n-- \ndef\n-- \nghi\n" =~ s/\n-- \n(?:(?!-- \n).)*?$//sr' 
abc 
-- 
def 

주 :

  1. 또 다른 정량 개질제 (예를 /.*+?/) 다음 경우에도 동일한 의미를 갖는다.
+0

@candyman, 업데이트 됨 – ikegami

1

당신이 미래에 정규 표현식을 이해하는 데 도움이 할 수있는 좋은 CPAN 모듈이있다 : 웹 사이트 반환을 통해 정규식을 실행 http://rick.measham.id.au/paste/explain.pl

: 당신은 여기의 온라인 버전을 찾을 수 있습니다 YAPE::Regex::Explain

은 다음과 같습니다 :

문서에 따르면 "Perl 버전 5.6 이후에 추가 된 정규식 구문, 특히 모든 공동 nstructs가 5.10 "으로 추가되었지만 실제로는 대부분의 regexes를 이해하는 데 도움을 줄 수 있어야합니다.

관련 문제