2014-09-18 13 views
5

Próbuję dopasować węzły w bazie danych Neo4j. Węzły mają właściwość o nazwie "nazwa" i używam wyrażenia regularnego w programie Cypher, aby dopasować to. Chcę tylko dopasować całe słowa, więc "javascript" nie powinien pasować, jeśli dostarczę ciąg "java". Jeśli ciąg do dopasowania jest kilku słów, tj. "Skrypt java", zrobię dwa oddzielne zapytania, jeden dla "java" i jeden dla "skryptu".Zapytanie Cypher z wyrażeniem regularnym

To, co mam tak daleko:

match (n) where n.name =~ '(?i).*\\bMYSTRING\\b.*' return n 

To działa, ale nie działa z niektórych znaków specjalnych, takich jak „+” lub „#”. Więc nie mogę wyszukać "C++" lub "C#" itp. Wyrażenie regularne w powyższym kodzie używa po prostu \ b dla granicy słowa. również ucieka, więc działa poprawnie.

Próbowałem niektóre wersje tego posta: regex to match word boundary beginning with special characters, ale to naprawdę nie działa, może zrobiłem coś złego.

Jak mogę wykonać tę pracę ze znakami specjalnymi w Cypher i Neo4j?

Odpowiedz

3

Spróbuj uciec przed znakami specjalnymi i poszukaj znaków bez słów, a nie granic słów. Na przykład;

match (n) where n.name =~ '(?i).*(?:\\W|^)C\\+\\+(?:\\W|$).*' return n 

Chociaż nadal ma pewne fałszywe alarmy, na przykład powyższe pasuje do "C+++".

W przypadku "znaku innego niż słowo, z wyjątkiem tego, że chcemy traktować znak + jako znak słowny", mogą działać następujące elementy.

match (n) where n.name =~ '(?i).*(?:[\\W-[+]]|^)C\\+\\+(?:[\\W-[+]]|$).*' return n 

Chociaż nie jest to obsługiwane przez wszystkie smaki regexp, i nie jestem pewien, czy obsługuje go Neo4j.

+1

Normalnie działałoby, ale granica słowa \ b działa tylko ze znakami alfanumerycznymi, więc nie pasuje do właściwości takich jak "C++" (która zaczyna się lub kończy specjalnym znakiem). Pasowałoby do właściwości takich jak "C++ c", ponieważ kończy się na "c". –

+0

@ Øyvind Zaktualizowano. – Taemyr

+0

To działało, ale było również dopasowane, jeśli przed napisaniem lub po nim były znaki, o których wspominasz w zaktualizowanej odpowiedzi. Czy istnieje sposób, aby dopasować tylko do całych słów? Czy zaktualizowana odpowiedź nie byłaby taka sama jak "(? I). * C \\ + \\ +. *? –

1

Możesz potwierdzić białe przestrzenie (lub nic w ogóle - granicę meczu) przed i za meczem, zamiast przekraczać granice słów. Zobacz to:

(?i).*(?<!\\S)MYSTRING(?!\\S).* 

Tutaj można pobawić z regex demo. Będzie pasował tylko do twojego ciągu znaków, jeśli znajduje się pomiędzy białymi znakami lub granicami przed i po twoim słowie. Można zdefiniować „interpunkcji”, jeśli trzeba, tak:

(?i).*(?<![^\\s.,$])MYSTRING(?![^\\s.,$]).* 
       ^^^ add boundaries ^^^ 

Wtedy będzie on pasował rawrssss MYSTRING. dd również.

Zobacz regex demo!

Powiązane problemy