Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: MySQL a MariaDB różnice w obsłudze wyrażeń regularnych
Forum PHP.pl > Forum > Bazy danych > MySQL
kaem
Witam,
MariaDB to system oparty na mysql'u, jednak ich wyrażenia regularne oparte są na PCRE a w MySQL'u na POSIXIE . Więcej na:
https://mariadb.atlassian.net/browse/MDEV-7127.
Chciałbym utworzyć zapytanie korzystające z REGEXP, które będzie działało na tych dwóch systemach bazodanowych. Mam teraz z grubsza coś takiego:
  1. SELECT * FROM firmy
  2. WHERE (firmy.nazwa RLIKE '(^|\\x{20})\\x{22}{1}amica\\x{22}{1}($|\\x{20})'

Jednak na MySQL dostaję błąd "SQLSTATE[42000]: Syntax error or access violation: 1139 Got error 'repetition-operator operand invalid' from regexp' ". Wcześniej w tym zapytaniu zamiast szesnastkowych reprezentacji
znaków (\\x{20} oznacza np. spację; więcej tutaj) używałem character setów czyli, np.
  1. RLIKE '(^|[[.space.]]) ...

ale to z kolei powodowało na MariaDB błąd "POSIX collating elements are not supported". Jak z pierwszego zapytania usunę operatory powtórzeń, czyli w tym przypadku jeden {1} to nie ma błędu.
Ktoś ma jakiś pomysł jak używać takich wyrażeń żeby działało na MySQL oraz MariaDB?
Dodam że potrzebuję obsługi następujących znaków:

  1. // na potrzeby działania w MariaDB
  2. $change = array('.' => "\\\x{2E}",
  3. ',' => "\\\x{2C}",
  4. ' ' => "\\\x{20}",
  5. '(' => "\\\x{28}",
  6. ')' => "\\\x{29}",
  7. '[' => "\\\x{5B}",
  8. ']' => "\\\x{5D}",
  9. '^' => "\\\x{5E}",
  10. '$' => "\\\x{24}",
  11. '\\' => "\\\x{5C}",
  12. '/' => "\\\x{2F}",
  13. '<' => "\\\x{3C}",
  14. '>' => "\\\x{3E}",
  15. '"' => "\\\x{22}",
  16. ':' => "\\\x{3A}"
  17. );


  1. //wcześniej gdy system działał tylko na MySQL były tak jak pisałem character sety:
  2. $change = array('.' => "[[.period.]]",
  3. ',' => "[[.comma.]]",
  4. ' ' => "[[.space.]]",
  5. '(' => "[[.left-parenthesis.]]",
  6. ')' => "[[.right-parenthesis.]]",
  7. '[' => "[[.left-square-bracket.]]",
  8. ']' => "[[.right-square-bracket.]]",
  9. '^' => "[[.circumflex-accent.]]",
  10. '$' => "[[.dollar-sign.]]",
  11. '\\' => "[[.backslash.]]",
  12. '/' => "[[.slash.]]",
  13. '<' => "[[.less-than-sign.]]",
  14. '>' => "[[.greater-than-sign.]]",
  15. '"' => "[[.quotation-mark.]]",
  16. ':' => "[[.colon.]]"
  17. );
Pyton_000
A nie możesz poprzedzić znak specjalny po prostu \\ ?
Crozin
Tak na szybko... czy w ogóle potrzebujesz tutaj wyrażeń regularnych? Chyba możesz to zamienić podwójnym warunkiem?
  1. ...WHERE name IN(' amica ', 'amica', ' "amica" ', '"amica"');
kaem
To jest część większego modułu wyszukiwania zaawansowanego, który został kiedyś przez inną osobę napisany ( albo nawet kilka osób ) sad.gif Czyli @Crozin niestety nie mogę użyć takiego zapytania, nie mogę również używać znaków ucieczki, bo skrypt padnie w innym miejscu... Ostatecznie może nie obejdzie się bez przebudowy i większych zmian w tym module, ale jeśli to możliwe chciałbym tego uniknąć.
Crozin
Podpowiedź: wyszukiwarka oparta o zwykłego RegExpa w bazie danych jest słabym narzędziem, zarówno wydajnościowo jak i jakościowo. Zainteresuj się narzędziami typu Solr o ile masz taką możliwość/chęć.

Cytat
nie mogę również używać znaków ucieczki, bo skrypt padnie w innym miejscu...
To wygląda na błąd, który należy w pierwszej kolejności poprawić. Co i dlaczego miałoby się wysypać?
Pyton_000
Popieram, to że znak ucieczki wysypie Ci system to jest poważny błąd. Nie wiemy nic o systemie na którym pracujesz ale to nie powinno mieć miejsca.
kaem
Z grubsza wygląda to tak, że mamy wyszukiwarkę, w której możemy używać znaków specjalnych sterujących wyszukiwaniem, takich jak np. *,+,-,",( i kilka innych. Np. wpisanie "ALA-MA" spowoduje znalezienie firm które mają w nazwie "ALA" ale nie mają "MA". Jeśli chcemy firmę "ALA-MA" to musimy wpisać "ALA\-MA" itd. itp. Skrypt to wszystko mieli, podmienia, dalej mili, znowu coś podmienia i tak dalej smile.gif, np malutki wycinek:
  1.  
  2. $field = str_replace(';,q,;', '\"', $field);
  3. $field = str_replace(';,m,;', '-', $field);
  4. $field = str_replace(';,p,;', '\+', $field);
  5. //escapowanie
  6. $field = $multibyte ? mb_ereg_replace('([\\\]){1}', '\\1\\1\\1\\1', $field) :
  7. ereg_replace('([\\\]){1}', '\\1\\1\\1\\1', $field);
i jest tego więcej (jak widać po ereg_replace skrypt ma już parę lat).
Dlatego zależy mi żeby to co miałem wcześniej i działało na mysql, czyli
  1. $change = array('.' => "[[.period.]]",
działało również na mariaDB, dlatego próbowałem z
  1. $change = array('.' => "\\\x{2E}",

ale gdy w wyrażeniu pojawia się operator potworzenia {JAKAŚLICZBA} to na MySQL się z kolei wywala. Oczywiście ostatecznie może się okazać, że konieczne będą zmiany/poprawki, ale na razie staram się to zrobić jak najmniejszym kosztem.
@Crozin dzięki, z chęcią zainteresuje się tym narzędziem.
Pyton_000
najmniejszym kosztem to jest postawić serwer MySQL tu, albo MariaDB tam (zależy pod co masz napisany system)
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.