Regexpy słyną z bycia językiem “tylko do zapisu”, często ciężko jest odcyfrować co autor regexpa miał na myśli. Jest (w perlowych i kompatybilnych) pewien ficzer który to ułatwia, mianowicie opcja x, powoduje ona że parser regexpów ignoruje komentarze, czyli taki np. dekoder daty (tak wiem że są liby, to tylko przykład ;))

my ($year, $mon, $mday, $hour, $min, $sec) = $date =~
  /(\d{1,4})\-(\d{1,2})\-(\d{1,2})\s+(\d{1,2})\:(\d{1,2})\:(\d{1,2}).*/;

można zapisać w formie:

my ($year, $mon, $mday, $hour, $min, $sec) = $date =~
  /(\d{1,4})\- # year-
   (\d{1,2})\- # month-
   (\d{1,2})\s+ # day + whitespace
   (\d{1,2})\: # hour:
   (\d{1,2})\: # min:
   (\d{1,2}) # sec:
   .* #rest of crap
  /x;

Trzeba tylko “wyescapować” wszystkie spacje (chociażby przez \s co oznacza “any whitespace” czyli też taby i \n)

Z innych przydatnych rzeczy to ściąga i edytor z tych “mniej znanych a przydatnych” :

  • (?:...) – pasywna grupa tzn matchuje ale nie będzie zwracane do zmiennych, czyli np (?:foo|bar)(.*) zwróci w zmiennej tylko zawartość bloku (.*) a nie foo/bar
  • \s i pokrewne, zamiast pisać \ (backslash spacja) czytelniej jest użyć \s które dodatkowo zmatchuje nam też taby i pare innych niewidocznych znaczków. \s+ jest przydatne, “matchuj jeden lub więcej whitespace”
  • {x,y} – zmatchuj od x do y znaków – np \d{3,} – więcej niż 3 cyfry, \S{5,9} – od 5 do 9 “nie-whitespace”
  • ? – powoduje że match będzie “ungreedy” czyli “zmatchuj minimalną liczbę znaków która będzie pasować, np gdy wrzucimy ciąg znaków “a:b:c” do regexpa (.*)\:(.*) to dostaniemy matche ‘a:b’ i ‘c’, gdy zrobimy matcha (.*?)\:(.*) na tym samym tekście to wynikiem będzie ‘a’ i ‘b:c’

Inną metodą na tworzenie regexpów jest “pokaż swojemu kotu jaki tekst chcesz zmatchować a potem posadź go na klawiaturze” ale to troszeczkę mniej czytelne ;]