[PL] Nie ma nic prostszego niż napisanie wolnego regexpa (RG-dev))

Ba17945a06aac247b06548d5afe341e8?s=47 mrzasa
February 22, 2018

[PL] Nie ma nic prostszego niż napisanie wolnego regexpa (RG-dev))

Prezentacja o wydajności regexpów, RG-Dev, Rzeszów, 22.02.2018

Ba17945a06aac247b06548d5afe341e8?s=128

mrzasa

February 22, 2018
Tweet

Transcript

  1. NIE MA NIC PROSTSZEGO NIŻ NIE MA NIC PROSTSZEGO NIŻ

    NAPISANIE WOLNEGO NAPISANIE WOLNEGO REGEXPA REGEXPA MACIEK RZĄSA MACIEK RZĄSA RG-Dev, 22.02.2018 @mjrzasa
  2. None
  3. None
  4. None
  5. I'm definitely guilty of this. When I throw a regex

    together, I never worry about performance; I know the target strings will generally be far too small to ever cause a problem. Jeff Atwood, 2006
  6. JEŚLI JEFF ATWOOD NIE DBA JEŚLI JEFF ATWOOD NIE DBA

    OD WYDAJNOŚĆ REGEXPÓW, OD WYDAJNOŚĆ REGEXPÓW, DLACZEGO JA POWINIENEM? DLACZEGO JA POWINIENEM?
  7. CO DALEJ? CO DALEJ? jak właściwie działają regexpy? wydajność podstawowych

    elementów zastosowania co może pójść nie tak? czy istnieją szybkie regexpy?
  8. RUBY DEVELOPER RUBY DEVELOPER @ TEXTMASTER @ TEXTMASTER w pracy:

    Ruby, Java, mongodb, elastic search automatyczne przygotowanie tekstu do tłumaczeń DDD, software that matters, agile dzielenie się wiedzą: Rzeszów Ruby User Group ( ) Politechnika Rzeszowska rrug.pl
  9. JAK WŁAŚCIWIE JAK WŁAŚCIWIE DZIAŁAJĄ DZIAŁAJĄ REGEXPY? REGEXPY?

  10. REGEXPY REGEXPY JĘZYK PROGRAMOWANIA W JĘZYKU JĘZYK PROGRAMOWANIA W JĘZYKU

    PROGRAMOWANIA PROGRAMOWANIA pattern = /<.*>/ pattern.match("text <br>") Pattern p = Pattern.compile("<.*>"); Matcher m = p.matcher(text <br>); boolean b = m.matches();
  11. WYRAŻENIA REGULARNE WYRAŻENIA REGULARNE I AUTOMATY I AUTOMATY gramatyka regularna

    wyrażenie regularne: abab|abbb automat skończony źródło: A -> abB B -> bb B -> ab https://swtch.com/~rsc/regexp/regexp1.html
  12. WYRAŻENIA REGULARNE WYRAŻENIA REGULARNE W JĘZYKACH PROGRAMOWANIA W JĘZYKACH PROGRAMOWANIA

    w teorii języków formalnych w silnikach wyrażeń regularnych a* a+ a|b a? a(a|b) a* a+ a|b a? a(a|b) a*? a++ \d \W (<!b)a \1... /(\w+)\1/` -> `papa WikiWiki`
  13. DWA RODZAJE SILNIKÓW DWA RODZAJE SILNIKÓW REGEXPÓW REGEXPÓW 1. Text

    directed Thompson 1968 grep, awk, sed 400 linii w C 2. Regex-directed Larry Wall, perl, 1987 Perl-Compatible Regular Expressions (java, ruby, .Net,...)
  14. PRZYKŁAD PRZYKŁAD źródło ilustracji na tym i kolejnych slajdach: /abab|abbb/

    =~ 'abbb' https://swtch.com/~rsc/regexp/regexp1.html
  15. None
  16. None
  17. CO JUŻ WIEMY? CO JUŻ WIEMY? regexpy - osobny język

    programowania dwa rodzaje silników (maszyn wirtualnych) - text-directed, regex-directed istotna jest ilość kroków i powrotów
  18. None
  19. WYDAJNOŚĆ WYDAJNOŚĆ PODSTAWOWYCH PODSTAWOWYCH ELEMENTÓW ELEMENTÓW powtórzenia alternatywa i klasy

  20. POWTÓRZENIA POWTÓRZENIA .* greedy (zachłanne) .*? lazy (leniwe) /<.*>/=~"<br />

    regexp text " => "<br/>" # so far so good /<.*>/=~"<abbr> regexp text </abbr>" => "<abbr> regexp text </abbr>" #hmmm... /<[^>]*>/=~"<abbr> regexp text </abbr>" => "<abbr>" # great! /<.*?>/=~"<abbr> regexp text </abbr>" => "<abbr>" # great!
  21. WARTO BYĆ LENIWYM? WARTO BYĆ LENIWYM? "<abbr> regexp text </abbr>"

    /<[^>]*>/ /<.*?>/
  22. LICZY SIĘ KONTEKST LICZY SIĘ KONTEKST "<br/> some really long

    text" <.*> 27 kroków <.*?> 7 kroków <[^>]*> 4 kroki "some really long text <br/> " <.*> 5 kroków <.*?> 7 kroków <[^>]*> 4 kroki
  23. PRAWIE PRAWIE ROBI RÓŻNICĘ ROBI RÓŻNICĘ possesive .++ wyszukiwanie liczb

    z jednostkami a co, jeśli napis prawie pasuje? 123cm; 32kg; 1m3; /^(\d+)(\w+);/ 123cm 32kg 1m3
  24. 19 KROKÓW 19 KROKÓW 9 KROKÓW 9 KROKÓW /^(\d+)(\w+);/ /^(\d++)(\w+);/

    # (Java, Ruby) /^(?>\d+)(\w+)/ #(.Net) /^(?=\d+)\1(\w+)/ #(JavaScript)
  25. POWTÓRZENIA POWTÓRZENIA różne podejścia do powrotów i początkowego zakresu: .*

    .*? .*+ wydajność zależna od kontekstu testy pozytywne: szukany string w różnych miejscach tekstu testy negatywne: napis bardzo podobny do szukanego
  26. ALTERNATYWY ALTERNATYWY

  27. KRÓTKIE ALTERNATYWY... KRÓTKIE ALTERNATYWY... Wyszukiwanie klas CSS product-size product- column

    product-info <div id='product-123' class='product-1200px product-summary'> </div> <div id='product-123' class='product-1200px product-info'> </div> /(product-size|product-column|product-info)/ # 192 kroki /product-(size|column|info)/ # 82 kroki
  28. ...ALBO KLASY ...ALBO KLASY Wyszukiwanie identyfikatorów product-123 <div id='product-123' class='product-1200px

    product-summary'> </div> <div id='product-124' class='product-1200px product-info'> </div> /product-(1|2|3|4|5|6|7|8|9|0)+/ # 29 kroków /product-(\d)+/ # 10 kroków
  29. WYSZUKIWANIE SŁÓW KLUCZOWYCH WYSZUKIWANIE SŁÓW KLUCZOWYCH albo FlashText /(Jan|Stefan|Marian|...)/ /(Rzeszów|Głogów|Boguchwała|Sokołów|...)/

    /(\.\.\.|\.\.\.|...)/
  30. REGEXPY VS FLASHTEXT - REGEXPY VS FLASHTEXT - WYSZUKIWANIE WYSZUKIWANIE

    źródło: www.analyticsvidhya.com
  31. REGEXPY VS FLASHTEXT - REGEXPY VS FLASHTEXT - ZASTĘPOWANIE ZASTĘPOWANIE

    źródło: www.analyticsvidhya.com
  32. ALTERNATYWY ALTERNATYWY jak najkrótsze podwyrażenia z dobrze określonym początkiem ograniczona

    ilość ścieżek
  33. TO WSZYSTKO TO DROBIAZG TO WSZYSTKO TO DROBIAZG To nie

    po to Was tu trzymam
  34. CATASTROPHIC CATASTROPHIC BACKTRACKING BACKTRACKING

  35. POWTÓRZENIE W POWTÓRZENIU POWTÓRZENIE W POWTÓRZENIU ..ale kto pisze takie

    regexy? /(a+)*b/ aaaaaaaaaab aaaaaaaaaa
  36. DZIAŁANIA ARYTMETYCZNE DZIAŁANIA ARYTMETYCZNE 320-12= 430- 32+1= /(\d+[-+])+=/ /(\d+[-+]?)+=/ /(\d+|\.?)+=/

    "320-12=" # 12 kroków "32-12+230=" # 18 kroków "32+12-320-2132+32123=" # 28 kroków "32+12-320-2132+32123" # 95 854 kroki
  37. COPY-PASTING COPY-PASTING (email validation) , Java Classname RegExLib, id=1757 ^([a-zA-Z0-9])(([\-.]|[_]+)?

    ([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1} (([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$ OWASP Validation Regex Repository /^(([a-z])+.)+[A-Z]([a-z])+$/ 'aaaaaaaaaaaaaaa'
  38. CZEGO UNIKAĆ? CZEGO UNIKAĆ? nachodzące się zakresy /\d+\w*/ nachodzace się

    alternatywy (\d+|\w+) odległe,krzyżujące się powtórzenia /.*-some text-.*;/ zagnieżdżone powtórzenia /(\d+)*\w/
  39. None
  40. KOMPUTERY TERAZ SĄ TAK KOMPUTERY TERAZ SĄ TAK SZYBKIE, ŻE

    NAWET 100 000 SZYBKIE, ŻE NAWET 100 000 KROKÓW NIE MA ZNACZENIA! KROKÓW NIE MA ZNACZENIA! kilka słów o zastosowaniach
  41. ZLICZANIE LICZB W TEKŚCIE ZLICZANIE LICZB W TEKŚCIE co może

    być prostszego? # liczba # 1, 3243, 4323 /\d+\s/ # liczba z częścią dziesiętną i minusem # -1, 1, 32.32, -2.2324 /-?(\d+\(\.\d+)?\s/ # liczba z częścią dziesiętną (kropka albo przecinek) # -23,23 4323.23 /-?(\d+\([.,]\d+)?\s)/
  42. ZLICZANIE LICZB W TEKŚCIE ZLICZANIE LICZB W TEKŚCIE # liczba

    z częścią dziesiętną i separatorami tysięcy # -21,321,321.1111 433.233,12 /(-?(\d+[,.]?)+)\s/ # j.w., lazy /(-?((\d+?[,.])+?)\s/ # j.w., possesive /(-?((\d++[,.])++)\s/
  43. None
  44. TESTY TESTY string = <<TEXT A text with 123.21231.231.23d a

    number: 12,212,234.12 Other 12 43 123.21231.22.22.2.33d Some other 9012,123123 -12 TEXT string =* 100 POSSESIVE = /(-?(\d++[,.]?)++)/ LAZY = /(-?(\d+?[,.]?)+?)/ NORMAL = /(-?(\d+[,.]?)+)/ def count_whole(string, regex) string.scan(/(?<=\s)#{regex}(?=\s)/).count end def count_split(string, regex) string.split.count{|s| s.match(/^#{regex}$/)} end
  45. CZAS I PAMIĘĆ CZAS I PAMIĘĆ whole possesive: 1556.6 i/s

    whole normal: 74.8 i/s - 20.81x slower whole lazy: 72.2 i/s - 21.55x slower split possesive: 49.4 i/s - 31.53x slower split normal: 30.9 i/s - 50.43x slower split lazy: 30.5 i/s - 51.03x slower whole normal: 67834 allocated whole possesive: 67852 allocated - 1.00x more whole lazy: 67852 allocated - 1.00x more split normal: 3020284 allocated - 44.52x more split possesive: 3047284 allocated - 44.92x more split lazy: 3047284 allocated - 44.92x more
  46. WYSZUKIWANIE W LOGACH WYSZUKIWANIE W LOGACH logi webserwera NASA, 196

    MB 199.72.81.55 - - [01/Jul/1995:00:00:01 -0400] "GET /history/apollo/ HTTP/1.0" 200 6245 unicomp6.unicomp.net - - [01/Jul/1995:00:00:06 -0400] "GET /shuttle/countdown/ HTTP/1.0" 200 3985
  47. DŁUGIE REGEXPY DŁUGIE REGEXPY /.* - - \[(.*)\] "((.+) ?)*"

    (.*) (.*)/ # 5m18,298s /.* - - \[(.*)\] "(.+) (.*) (HTTP\/.*)" (.*) (.*)/ # 0m10,013s /\S* - - \[([^\]]*)\] "(\S+) (\S*) (HTTP\/\d.\d)" (\d+) (\d+)/ # 0m5,897s
  48. REDOS - CZYLI CO MOŻE REDOS - CZYLI CO MOŻE

    PÓJŚĆ NIE TAK? PÓJŚĆ NIE TAK?
  49. JAK ZAMULIĆ FRONTEND? JAK ZAMULIĆ FRONTEND? vue.js

  50. JAK ZAJĄĆ 100% PROCESORA? JAK ZAJĄĆ 100% PROCESORA? Witaj! →

    ¡Hola! → Salut ! # Źródła funkcji ::Typography.to_html_french # Wstaw cienką spację przed znaki interpunkcyjne text.gsub(/(\s|)+([!?;]+(\s|\z))/, '&thinsp;\2\3') # <-58 spacji -> GET /wp-login.php HTTP/1.1 69 GET /show.aspx HTTP/1.1 15 klient Discourse, opisane przez Sama Saffrona
  51. POZWÓLMY UŻYTKOWNIKOM PISAĆ POZWÓLMY UŻYTKOWNIKOM PISAĆ REGEXPY REGEXPY feature request

    (<.*>\s*)* alternatywne silniki regexpów (text directed) ograniczenie ilości dostępnych funkcji ograniczenie powrotów (backtrackingu) timeouty
  52. None
  53. None
  54. DOBRE PRAKTYKI DOBRE PRAKTYKI .* => [^X]* .*? => [^X]*

    (pre-d1|pre-e2|...) => pre- (d1|e2|...) (,|;|\.) => [,.;] (\d+[+-]?)+ => (\d+[+-])+\d+ \w+-\d+ => \w+-\d++, \w+-(?>\d+)
  55. WNIOSKI WNIOSKI optymalizacja regexpów: minimalizacja ilości kroków i powrotów główne

    problemy: nachodzące się zakresy lub alternatywy, zagnieżdżone powtórzenia testy: poprawny, niepoprawny, prawie poprawny napis, różne konfiguracje każdy silnik jest inny - testuj wydajność na swoim
  56. MATERIAŁY MATERIAŁY Mastering Regular Expressions, 3rd Edition, Jefferey Friedl, 2009

    i kolejne części (1-4) podziękowania dla kszubrycht :) http://www.rexegg.com https://www.regular-expressions.info https://regex101.com/ Russ Cox aplikacja testowa - oryginał OWASP ReDoS Loggly: 5 techniquess Loggly: regexes bad better...
  57. None
  58. None