2013-08-07 19 views
6

Pracuję nad pewnym kodem Perla w aplikacji Request Tracker 4.0 i napotkałem błąd, gdy wiadomość żądającego biletu jest odcięta. Jestem nowy w Perlu, wykonałem trochę pracy z wyrażeń regularnych, ale mam pewne problemy z tym nawet po dość lekturze.

mam zawężony mój problem w dół do tej linii kodu:

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

nie w pełni zrozumieć, co robi i chciałby lepszego wyjaśnienia.

Rozumiem, że s/ / pasuje do wzorca \n-- \n.*?$ i zastępuje go nic. Nie mam pojęcia, co robi

Oto moja podstawowa znajomość:

  • . jest dowolny znak z wyjątkiem \ n
  • * wynosi 0 lub więcej razy z poprzednim znakiem
  • ? wynosi 0 lub 1 czasy poprzedniego znaku
  • $ jest koniec ciągu znaków

Następnie, z tego co rozumiem, ostateczny s powoduje, że . dopasuj nowe linie

Tak więc, w przybliżeniu, zastępujemy tekst zaczynający się od \n-- \n - ta linia kodu powoduje pewne wątpliwe zachowania, które chciałabym rozwiązać, jeśli ktoś może wyjaśnić, co tu się dzieje.

Czy ktoś może wyjaśnić, co robi ta linia? Czy po prostu usuwa cały tekst po pierwszym \n-- \n lub czy jest w nim więcej?

długo zdyszany kwestia część/real-life (nie musisz tego czytać, aby odpowiedzieć na pytanie)

Mój dokładny problemem jest to, że cięcia cytowany zawartość w podpisie.

Więc jeśli Powiadom od klienta mówi:

Co się dzieje z rzędu ABCD?
- Niektóre klienta

Odpowiedź personel mówi (nota utratę podpisem klienta)

Jest wysyłka dzisiaj

Co się dzieje z rzędu ABCD?

Klient odpowiada

ja nie rozumiem, nie wysyłamy !!!
- Niektóre klienta

Jest wysyłka dzisiaj

Co się dzieje z rzędu ABCD?

Kiedy odpowiadać ich wiadomość odetnie u - który zabija cały kontekst.

To wysłane dzisiaj, śledzenie numeru 12345

ja nie rozumiem, nie wysyłamy !!!

i prowadzi do dalszej pracy wyjaśniając, co to jest porządek, itp

Odpowiedz

8

Jesteś prawie poprawne: usuwa wszystko od ostatniego wystąpienia „\ n- \ n” do końca . To, że to nie usuwa wszystkiego od pierwszego wystąpienia, jest spowodowane przez nieagresywnego operatora ? - mówi silnikowi regex, aby pasował do najkrótszej postacią nośnika z poprzedniego wzoru (.*).

Co to oznacza: w komunikacji e-mailowej podpis jest zwykle oddzielany od treści wiadomości dokładnie według tego wzoru: linia składająca się z dokładnie dwóch kresek i pojedynczej spacji końcowej. Dlatego to, co robi regex, usuwa wszystko, zaczynając od separatora znaków na końcu.

Teraz to, co robi klient (ręcznie lub przez klienta poczty e-mail), jest dodawane do cytowanej odpowiedzi e-maila po separatorze podpisów. Jest to bardzo nietypowe: cytowana odpowiedź musi znajdować się przed modyfikatorem podpisu. Nie znam żadnego klienta poczty e-mail, który robi to celowo, ale niestety jest mnóstwo programów, które po prostu pobierają pocztę elektroniczną z (od problemów z zestawem znaków po cytowanie do niezgodności z SMTP możesz zrobić niesamowitą liczbę błędów) , więc nie byłbym zaskoczony, gdyby dowiedzieli się, że rzeczywiście tacy klienci.

Inną możliwością jest to, że jest to wpływ klienta - np. Podpisanie własnego nazwiska po --. Podejrzewam jednak, że nie jest to robione ręcznie, ponieważ ludzie rzadko wstawiają spację po dwóch myślnikach, po których następuje podział wiersza.

+1

Thunderbird przynajmniej oferuje opcję. Możesz wybrać, czy chcesz umieścić cytaty powyżej lub poniżej podpisu. Jest wystarczająco inteligentny, aby wyciąć część '- \ n' podczas odpowiadania, ale wycina też własne cytaty. I Outlook nie dba o ogranicznik i zawsze umieszcza cytaty pod podpisem (w którym sam musisz umieścić ogranicznik). W TheBat! umieszczasz cytaty tam, gdzie chcesz je w szablonie. – simbabque

2

Gdy ? następuje kwantyfikator (?, *, + lub {m,n}) modyfikuje żarłoczność tego kwantyfikatora [1]. Zwykle kwantyfikatory te pasują do większości znaków, jak to możliwe, ale z wartościami ? odpowiadają najmniejszym.

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

wyjściowa:

bc123 
bc 

Ponieważ istnieją dwa miejsca $ może pasujących (przed tylną nowej linii lub na końcu ciągu), ten ma następujący efekt:

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

Wyjście:

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

Zapewnia, że ​​znak nowej linii kończącej ostatnią linię nie zostanie usunięty. Poniżej przedstawiono bardziej proste odpowiedniki:

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

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

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

Zauważ, że usunie począwszy od pierwszego --.

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

Jeśli chcesz rozpocząć usuwanie od ostatniej, będziesz musiał wymienić .* z czymś gwarantowanej nie pasujące --.

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

Uwagi:

  1. ma również te same znaczenia, jeśli następuje jeszcze modyfikatora kwantyfikatora (np /.*+?/).
+0

@candyman, Zaktualizowano – ikegami

1

Jest ładny moduł CPAN, które mogą pomóc w zrozumieniu wyrażeń regularnych w przyszłość: YAPE::Regex::Explain

można znaleźć wersję online tutaj: http://rick.measham.id.au/paste/explain.pl

Prowadzenie regex przez zwrotów www co następuje:

NODE      EXPLANATION 
-------------------------------------------------------------------------------- 
    \n      '\n' (newline) 
-------------------------------------------------------------------------------- 
    --      '-- ' 
-------------------------------------------------------------------------------- 
    \n      '\n' (newline) 
-------------------------------------------------------------------------------- 
    .*?      any character except \n (0 or more times 
          (matching the least amount possible)) 
-------------------------------------------------------------------------------- 
    $      before an optional \n, and the end of the 
          string 

Zgodnie z docs, „nie ma wsparcie dla składni wyrażeń regularnych dodanej po Perl w wersji 5.6, szczególnie w przypadku jednoczesnego nstructs dodane w 5.10 ", ale w praktyce nadal powinieneś być w stanie go użyć, aby zrozumieć większość wyrażeń, które napotkasz.

Powiązane problemy