【问题标题】:Cypher query with regular expression带有正则表达式的密码查询
【发布时间】:2014-09-18 09:27:37
【问题描述】:

我正在尝试匹配 Neo4j 数据库中的节点。节点有一个名为“name”的属性,我在 Cypher 中使用正则表达式来匹配它。我只想匹配整个单词,所以如果我提供字符串“java”,“javascript”不应该匹配。如果要匹配的字符串是多个单词,即“java script”,我将执行两个单独的查询,一个用于“java”,一个用于“script”。

这是我目前所拥有的:

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

这可行,但它不适用于某些特殊字符,如“+”或“#”。所以我无法搜索“C++”或“C#”等。上面代码中的正则表达式只是使用 \b 作为单词边界。它也在转义它,因此它可以正常工作。

我尝试了这篇帖子的某些版本:regex to match word boundary beginning with special characters,但它并没有真正起作用,也许我做错了什么。

如何使用 Cypher 和 Neo4j 中的特殊字符进行这项工作?

【问题讨论】:

    标签: regex neo4j cypher


    【解决方案1】:

    尝试转义特殊字符并寻找非单词字符而不是单词边界。例如;

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

    虽然这仍然有一些误报,例如上面会匹配“c++”。

    对于“非单词字符,除了我们想将 + 视为单词字符”,以下可能有效。

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

    虽然并非所有正则表达式都支持这一点,但我不确定 Neo4j 是否支持这一点。

    【讨论】:

    • 这通常可以工作,但 \b 单词边界仅适用于字母数字字符,因此它不匹配诸如“c++”之类的属性(以特殊字符开头或结尾)。它会匹配像“c++c”这样的属性,因为它以“c”结尾。
    • 这是有效的,但如果您在更新的答案中提到的字符串之前或之后有字符,它也会匹配。有没有办法让它只匹配整个单词?更新后的答案会不会和 '(?i).*C\\+\\+.*' 一样?
    • @Øyvind 答案与 '(?i).*C\\+\\+.*' 不同,因为它会匹配 c++c。
    • @Øyvind 要使其仅匹配整个单词,您需要明确说明整个单词的含义。正则表达式引擎将单词边界视为单词字符和非单词字符之间的边界,但这对您不起作用,因为您想将“c++c”视为单个单词。您可以将 "\\W" 替换为 "\\s" 以查找两侧有空格的匹配项。或使用“”来查找两侧有空格字符的匹配项。或者使用符合您标准的自定义字符组。
    • 好吧,我的边界是空格,也就是分隔的单词。当我用 \\s 替换 \\W 时,它按预期工作(测试有限)。我是否需要检查空格字符和空格,它们不一样?
    【解决方案2】:

    您可以在匹配前后断言空格(或根本不使用 - 匹配边界),而不是断言单词边界。看到这个:

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

    在这里,您可以使用regex demo。只有在单词前后的空格或边界之间,它才会匹配您的字符串。如果需要,您可以定义“标点符号”,如下所示:

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

    那么它也会匹配rawrssss MYSTRING. dd

    查看regex demo

    【讨论】:

      猜你喜欢
      • 2012-10-04
      • 1970-01-01
      • 2011-12-30
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      相关资源
      最近更新 更多