• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Ruby Regex - 'If'

Object Storage Arubacloud
0 głosów
291 wizyt
pytanie zadane 5 sierpnia 2018 w Ruby przez DeBos123 Nałogowiec (44,950 p.)

Witam, ma takiego regex'a:

/#(include|import) ([\w+\/]+.js)/

Chciałbym do niego dodać coś podobnego do if'a, żeby regex dodatkowo 'łapał':

/( as \w+)/

jeżeli w pierwszej grupie 'złapał' 'import'.

Da się coś takiego zrobić samymi regex'ami?

1 odpowiedź

0 głosów
odpowiedź 5 sierpnia 2018 przez Tomek Sochacki Ekspert (227,510 p.)

Nie znam Ruby więc nie wiem jak tam dokładnie wygląda składnia importów i include, ale może coś takiego:

  1. /#(include|import( as \w+)?) ([\w+\/]+.js)/

    Czyli dodanie opcjonalnej grupy przechwytującej " as \w+" ale tylko gdy wczesniej jest import, z tymże wtedy w dopasowanej grupie nr 1 będzie zarówno "import" jak i "as ...", w drugiej samo "as.." i dopiero w trzeciej grupie nazwa pliku z ".js".

  2. /#(include|import)( as \w+)? ([\w+\/]+.js)/

    Wtedy w pierwszej grupie będzie samo słowo "import" lub "include", w drugiej "as.." jeśli wystąpi, i w trzeciej nazwa pliku. Tyle, że w tym rozwiązaniu grupę z "as.." można będzie dopasować również gdy będzie słowo "include" ale pytanie czy to jest poprawne składniowo w Ruby, tzw. czy taki przypadek w ogóle istnieje? (ja nie wiem, dlatego pytam).

  3. Ewentualnie jeśli oba ww. regexp nie spełniają założeń to można będzie pokombinować z tzw. dopasowaniami wstecznymi ale to musiałbyś dać z 2-3 przykładowe ciągi znaków jakie wejdą do regexp i co oczekujesz aby dopasowano.

 

komentarz 5 sierpnia 2018 przez DeBos123 Nałogowiec (44,950 p.)

Nie znam Ruby więc nie wiem jak tam dokładnie wygląda składnia importów i include

'import' i 'include' to w tym przypadku zwykłe napisy.

Podam ci 3 przykłady, bo może nie sprecyzowałem do końca o co mi chodzi.

#include 'abc.js' => ['include', 'abc.js']

#import 'abc.js' as abc => ['import', 'abc.js', 'abc']

#include 'abc.js' as abc => ['include', 'abc.js'']

Chcę, żeby ta część ( as \w+) była 'łapana' tylko jeżeli w pierwszej grupie był 'import'

komentarz 5 sierpnia 2018 przez Tomek Sochacki Ekspert (227,510 p.)

A coś takiego? Nie znam ruby, więc napisałem w JS, ale regexp jest taki sam wszędzie:

const regexp = /#(include|import)\s+['"]([\w/]+\.js)['"](?:(?<=import.+\.js['"])(?: as (.+)))?/;

const test1 = "#include 'abc.js'".match(regexp);
test1[1]; //"include"
test1[2]; //"abc.js"
test1[3]; //undefined

const test2 = "#import 'abc.js' as abc".match(regexp);
test2[1]; //"import"
test2[2]; //"abc.js"
test2[3]; //"abc"

const test3 = "#include 'abc.js' as abc".match(regexp);
test3[1]; //"include"
test3[2]; //"abc.js"
test3[3]; //undefined

undefined w JS oznacza, że nie dopasowano w tym wypadku żadnego elementu do grupy odpowiednio 1, 2 i 3. Metoda match w JS działa tak (w tym wypadku), że zwraca tablicę, pierwszy element to całe dopasowanie (nas nie interesuje), kolejne to poszczególne grupy.

Potestuj sobie na różnych swoich przypadkach i daj znać czy działa, jeśli tak to możemy co nie co ten wzorzec uprościć bo ten jest taki pisany na szybko i testowany tylko na tych 3 wariantach.

komentarz 6 sierpnia 2018 przez DeBos123 Nałogowiec (44,950 p.)

regexp jest taki sam wszędzie

Regex'y nie są wszędzie takie same: https://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines.

A co do samego regex'a, który mi podałeś to dostaje błąd: 'Invalid pattern in look-behind'.

Regex'y jakby co testuje tutaj: http://rubular.com/

komentarz 6 sierpnia 2018 przez Tomek Sochacki Ekspert (227,510 p.)
pewne roznice owszem sa ale zasady są te same. widocznie w ruby lockbehind ma nieco inną skladnie, ja niechciałem znam ruby ale to na pewno w dokumentacji bedzie.
komentarz 6 sierpnia 2018 przez Tomek Sochacki Ekspert (227,510 p.)
Wiesz co, poczytałem trochę i jeśli dobrze zrozumiałem, to Ruby w lockbehind wymaga określenia dokładnej długości wzorca, nie dopuszcza więc tu kwantyfikatorów, ale to tak na szybko poczytane na SO i nie wiem jak to się ma do różnych wersji Rubiego.

A może w takim razie inaczej podejdziemy do problemu...

Możemy podzielić ciąg zawsze na 3 grupy niezależnie od tego czy pierwsza z nich przechwyci import czy include, druga zawsze dostanie file.js, a trzecia nazwę jako "as" jeśli będzie (jeśli nie to grupa będzie pustym ciągiem, chyba, że w ruby jest to inaczej).

I następnie drugi etap walidacji, czyli mamy naszą tablicę 3 elementów i jeśli pierwszy z nich to "include" i jednocześnie trzeci element nie jest pusty (czyli znalazło jakieś "as...") to usuwamy ten 3 element, robimy go pustym ciągiem itp.

Chodzi o rezygnację z lockbehind bo widzę, że ruby tego za bardzo nie lubi i zrobienie po prostu rozwiązania dwuetapowo, co myślisz?
komentarz 8 sierpnia 2018 przez DeBos123 Nałogowiec (44,950 p.)
Nie odpisywałem przez jakiś czas z powodu braku internetu i przez ten czas sam próbowałem cokolwiek zrobić z tym regex'em.

Doszedłem do wniosku, że zrobienie dwóch regex'ów będzie w moim przypadku 'lepsze' i czytelniejsze, więc tak właśnie zrobiłem, ponieważ ruby ma problem z look-behind i nie mogę osiągnąć tego co chciałem na początku.

Dziękuję za pomoc i poświęcony czas.
komentarz 8 sierpnia 2018 przez Tomek Sochacki Ekspert (227,510 p.)
Grunt to znaleźć rozwiązanie :) A swoją drogą to ciekawe z tym lockbehind w ruby... aż w wolnej chwili będę musiał poszukać info dlaczego tak to działa :)

Podobne pytania

0 głosów
1 odpowiedź 141 wizyt
pytanie zadane 9 lipca 2023 w Ruby przez whiteman808 Obywatel (1,820 p.)
+1 głos
1 odpowiedź 259 wizyt
pytanie zadane 1 lutego 2022 w Ruby przez doskanoness Obywatel (1,240 p.)
–4 głosów
4 odpowiedzi 786 wizyt
pytanie zadane 6 września 2021 w Ruby przez Teknal Początkujący (290 p.)

92,539 zapytań

141,382 odpowiedzi

319,476 komentarzy

61,928 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...