2014-09-18 12 views
5

Tôi đang cố gắng khớp các nút trong cơ sở dữ liệu Neo4j. Các nút có thuộc tính được gọi là "name" và tôi đang sử dụng cụm từ thông dụng trong Cypher để khớp với điều này. Tôi chỉ muốn phù hợp với toàn bộ từ, vì vậy "javascript" không nên phù hợp nếu tôi cung cấp chuỗi "java". Nếu chuỗi khớp với một vài từ, tức là "tập lệnh java", tôi sẽ thực hiện hai truy vấn riêng biệt, một cho "java" và một cho "script".Truy vấn Cypher với cụm từ thông dụng

Đây là những gì tôi có cho đến nay:

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

này hoạt động, nhưng nó không làm việc với một số ký tự đặc biệt như "+" hoặc "#". Vì vậy, tôi không thể tìm kiếm cho "C + +" hoặc "C#" vv Các biểu thức chính quy trong mã trên chỉ là sử dụng \ b cho ranh giới từ. nó cũng thoát nó để nó hoạt động chính xác.

Tôi đã thử một số phiên bản của bài đăng này: regex to match word boundary beginning with special characters nhưng nó không thực sự hoạt động, có thể tôi đã làm điều gì sai.

Tôi làm cách nào để làm việc này với các ký tự đặc biệt trong Cypher và Neo4j?

Trả lời

3

Hãy thử thoát các ký tự đặc biệt và tìm kiếm các ký tự không phải từ thay vì các đường biên từ. Ví dụ;

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

Mặc dù điều này vẫn có một số mặt tích cực sai, ví dụ như trên sẽ khớp với "C+++".

Đối với "Ký tự không phải từ, ngoại trừ việc chúng tôi muốn xem + dưới dạng ký tự từ", điều sau có thể hoạt động.

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

Mặc dù điều này không được hỗ trợ bởi tất cả các hương vị regexp và tôi không chắc liệu Neo4j có hỗ trợ điều này hay không.

+1

Điều này thường hoạt động, nhưng ranh giới \ b chỉ hoạt động với các ký tự chữ và số để nó không khớp với các thuộc tính như "C++" (bắt đầu hoặc kết thúc bằng ký tự đặc biệt). Nó sẽ khớp với các thuộc tính như "C++ c" vì nó kết thúc bằng "c". –

+0

@ Øyvind Đã cập nhật. – Taemyr

+0

Điều này đang hoạt động, nhưng nó cũng phù hợp nếu có các ký tự trước hoặc sau chuỗi như bạn đề cập trong câu trả lời được cập nhật. Có cách nào để làm cho nó chỉ phù hợp với toàn bộ từ? Câu trả lời không được cập nhật sẽ giống như '(? I). * C \\ + \\ +. *'? –

1

Bạn có thể khẳng định khoảng trắng (hoặc không có gì cả - ranh giới của trận đấu) trước và sau trận đấu của bạn thay vì khẳng định ranh giới từ. Xem phần này:

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

Tại đây, bạn có thể fiddle với regex demo. Nó sẽ chỉ phù hợp với chuỗi của bạn nếu nó nằm giữa khoảng trắng hoặc ranh giới cho trước và sau từ của bạn. Bạn có thể xác định "dấu chấm câu" nếu cần, như sau:

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

Sau đó, nó cũng sẽ khớp với rawrssss MYSTRING. dd.

Xem regex demo!

Các vấn đề liên quan