Syndrom pochylonej wykałaczki

W programowaniu komputerowym syndrom pochylonej wykałaczki ( LTS ) to sytuacja, w której cytowane wyrażenie staje się nieczytelne, ponieważ zawiera dużą liczbę znaków ucieczki , zwykle odwrotnych ukośników („\”), aby uniknąć kolizji ograniczników .

Oficjalna dokumentacja Perla wprowadziła ten termin do szerszego użycia; tam fraza jest używana do opisania wyrażeń regularnych pasujących do ścieżek w stylu uniksowym , w których elementy są oddzielone ukośnikami / . Ukośnik jest również używany jako domyślny ogranicznik wyrażenia regularnego, więc aby mógł być użyty dosłownie w wyrażeniu, musi być poprzedzony ukośnikiem odwrotnym \ , co prowadzi do częstych ukośników ze znakiem ucieczki reprezentowanych jako \/ . W przypadku podwojenia, jak w adresach URL, daje to \/\/ dla znaku ucieczki // . Podobne zjawisko występuje w ścieżkach DOS / Windows , gdzie ukośnik odwrotny jest używany jako separator ścieżki, co wymaga podwójnego ukośnika odwrotnego \\ - można go następnie ponownie zmienić w celu wyrażenia regularnego wewnątrz ciągu znaków ze znakiem ucieczki, wymagającego dopasowania \\\\ pojedynczy ukośnik odwrotny. W skrajnych przypadkach, takich jak wyrażenie regularne w łańcuchu ze zmianą znaczenia, dopasowanie jednolitej konwencji nazewnictwa (która zaczyna się od \\ ) wymaga 8 ukośników odwrotnych \\\\\\\\ z powodu 2 ukośników odwrotnych, z których każdy ma podwójną zmianę znaczenia.

LTS pojawia się w wielu językach programowania iw wielu sytuacjach, w tym we wzorcach pasujących do identyfikatorów URI (Uniform Resource Identifiers ) oraz w programach wyświetlających tekst w cudzysłowach. Wiele chin należy do tej drugiej kategorii.

Przykład wzoru

Rozważmy następujące wyrażenie regularne Perla, którego celem jest dopasowanie identyfikatorów URI, które identyfikują pliki w katalogu pub witryny FTP :

 m  /  ftp:\/\/[^\/]*\/pub\/  / 

Perl, podobnie jak wcześniej sed , rozwiązuje ten problem, pozwalając wielu innym znakom być ogranicznikami wyrażenia regularnego. Na przykład następujące trzy przykłady są równoważne wyrażeniu podanemu powyżej:

m{ftp://[^/]*/pub/} m#ftp://[^/]*/pub/# m!ftp://[^/]*/pub/!

Lub to wspólne tłumaczenie, aby zamienić ukośniki odwrotne na ukośniki:

 tr  /\\/  \  // 

może być łatwiejszy do zrozumienia, gdy jest napisany w ten sposób:

 tr  {  \\  }{  /  } 

Przykład cytowanego tekstu

Program Perla do drukowania tagu łącza HTML, w którym adres URL i tekst łącza są przechowywane odpowiednio w zmiennych $url i $text , może wyglądać tak. Zwróć uwagę na użycie ukośników odwrotnych, aby uniknąć cudzysłowów:

  print  "<a href=\"$url\">$text</a>"  ; 

Używanie pojedynczych cudzysłowów do oddzielania łańcucha nie jest wykonalne, ponieważ Perl nie interpretuje zmiennych wewnątrz łańcuchów ujętych w pojedyncze cudzysłowy. Na przykład poniższy kod nie działałby zgodnie z przeznaczeniem:

  drukuj  '<a href="$url">$tekst</a>' 

Korzystanie z funkcji printf jest opłacalnym rozwiązaniem w wielu językach (Perl, C , PHP ):

   printf  (  '<a href="%s">%s</a>'  ,  $url  ,  $text  ); 

Operator qq w Perlu pozwala na dowolny ogranicznik:

 
 
  drukuj  qq{<a href="$url">$text</a>}  ;  drukuj  qq|<a href="$url">$tekst</a>|  ;  drukuj  qq(<a href="$url">$text</a>)  ; 

W tym przypadku dokumenty szczególnie dobrze nadają się do ciągów wielowierszowych; jednak dokumenty Perla nie pozwalały na prawidłowe wcięcia przed wersją 5.26. Ten przykład pokazuje składnię Perla:

 

 drukuj  <<  HERE_IT_ENDS  ;  <a href="$url">$text</a>  HERE_IT_ENDS 

Inne języki

C#

Język programowania C# obsługuje LTS za pomocą symbolu @ na początku literałów łańcuchowych, przed początkowymi znakami cudzysłowu, np.

    string  filePath  =  @"C:\Foo\Bar.txt"  ; 

zamiast wymagać w inny sposób:

    string  filePath  =  "C:\\Foo\\Bar.txt"  ; 

C++

C ++ 11 dodaje surowe łańcuchy znaków :

    std  ::  string  filePath  =  R  "  (  C:\Foo\Bar.txt  )  "  ; 

Jeśli ciąg zawiera znaki )" , można użyć opcjonalnego ogranicznika, takiego jak d w poniższym przykładzie:

    std  ::  regex  re  {  R  "  d(  s/"\([^"]*\)"/'\1'/g  )d  "  }; 

Iść

Go wskazuje, że łańcuch jest nieprzetworzony, używając znaku wstecznego jako separatora:

   s  :=  `C:\Foo\Bar.txt` 

Surowe ciągi znaków mogą zawierać dowolne znaki oprócz kresek wstecznych; nie ma kodu ucieczki dla backticka w nieprzetworzonym łańcuchu. Surowe ciągi mogą również obejmować wiele wierszy, jak w tym przykładzie, gdzie ciągi s i t są równoważne:

  


   s  :=  `Ciąg, który  obejmuje wiele  wierszy.`  t  :=  "Ciąg, który\nrozciąga się na wiele\nlinii." 

Pyton

Python ma podobną konstrukcję, używając r :

   filePath  =  r  "C:\Foo\Bar.txt" 

Można ich również używać razem z potrójnymi cudzysłowami:

  
 przykład  =  r  """Pierwszy wiersz: "C:\Foo\Bar.txt"  Drugi wiersz: nic""" 

Rubin

Ruby używa pojedynczego cudzysłowu, aby wskazać nieprzetworzony ciąg znaków:

   filePath  =  'C:\Foo\Bar.txt' 

Ma również literały procentowe wyrażeń regularnych z wyborem ogranicznika, takiego jak Perl:



 %  r  {ftp://[^/]*/pub/}  %  r  #ftp://[^/]*/pub/#  %  r  !ftp://[^/]*/pub/! 

Rdza

Rust używa wariantu przedrostka r :

               
              
           
    "  \x52  "  ;  // R  r"\x52"  ;  // \x52  r#""foo""#  ;  // "foo"  r##"foo #"# bar"##  ;  // foo #"# bar 

Literał zaczyna się od r , po którym następuje dowolna liczba # , po której następuje jeden " . Dalsze " zawarte w literale są uważane za część literału , chyba że następuje po nich co najmniej tyle # , ile użyto po otwarciu r .

Scala

Scala pozwala na użycie potrójnych cudzysłowów, aby uniknąć nieporozumień:

   
    val  filePath  =  """C:\Foo\Bar.txt"""  val  pubPattern  =  """ftp://[^/]*/pub/"""  r 

Potrójne cudzysłowy pozwalają również na ciągi wielowierszowe, jak pokazano tutaj:

   
 val  text  =  """Pierwsza linia,  druga linia.""" 

Sed

Sed , szczególnie te używające operatora „s”, są bardzo podobne do Perla (sed jest poprzednikiem Perla). Domyślnym ogranicznikiem jest „/”, ale można użyć dowolnego ogranicznika; wartością domyślną jest s / regexp / replacement / , ale s : regexp : replacement : jest również poprawną formą. Na przykład, aby dopasować katalog „pub” (jak w przykładzie Perla) i zamienić go na „foo”, domyślnym ustawieniem (z ukośnikami) jest

 s  /  ftp:\/\/[^\/]*\/pub\/  /  foo  / 

Zamiast tego użycie wykrzyknika („!”) jako ogranicznika daje wynik

 s  !  ftp://[^/]*/pub/  !  fuj  ! 

Zobacz też