Javascript正则表达式模式将多个字符串(AND、OR)与单个字符串匹配

Javascript正则表达式模式将多个字符串(AND、OR)与单个字符串匹配,javascript,regex,match,Javascript,Regex,Match,我需要根据一个相当复杂的查询筛选字符串集合-在其“原始”形式中,它如下所示: nano* AND (regulat* OR *toxic* OR ((risk OR hazard) AND (exposure OR release)) ) ^ # Anchor search to start of string (?=.*\bnano) # Assert that the string contains a word that starts with

我需要根据一个相当复杂的查询筛选字符串集合-在其“原始”形式中,它如下所示:

nano* AND (regulat* OR *toxic* OR ((risk OR hazard) AND (exposure OR release)) )
^                 # Anchor search to start of string
(?=.*\bnano)      # Assert that the string contains a word that starts with nano
(?=               # AND assert that the string contains...
 (?:              #  either
  .*\bregulat     #   a word starting with regulat
 |                #  OR
  .*toxic         #   any word containing toxic
 |                #  OR
  (?=             #   assert that the string contains
   .*             #    any string
   (?:            #    followed by
    \brisk\b      #    the word risk
   |              #    OR
    \bhazard\b    #    the word hazard
   )              #    (end of inner OR alternation)
  )               #   (end of first AND condition)
  (?=             #   AND assert that the string contains
   .*             #    any string
   (?:            #    followed by
    \bexposure\b  #    the word exposure
   |              #    OR
    \brelease\b   #    the word release
   )              #    (end of inner OR alternation)
  )               #   (end of second AND condition)
 )                #  (end of outer OR alternation)
)                 # (end of lookahead assertion)
要匹配的字符串之一的示例:

Workshop on the Second Regulatory Review on Nanomaterials, 30 January 2013, Brussels
所以,我需要使用AND或和通配符进行匹配-所以,我想我需要在JavaScript中使用正则表达式

我有它所有的循环正确,过滤和一般工作,但我100%肯定我的正则表达式是错误的-和一些结果被错误地忽略-这里是:

/(nano[a-zA-Z])?(regulat[a-zA-Z]|[a-zA-Z]toxic[a-zA-Z]|((risk|hazard)*(exposure|release)))/i
任何帮助都将不胜感激-我真的无法正确地抽象我的思想来理解这个语法

更新:

很少有人指出正则表达式构造顺序的重要性,但是我无法控制将要搜索的文本字符串,因此我需要找到一个无论顺序如何都能工作的解决方案

更新:

最终使用了一个PHP解决方案,由于TwitterAPI 1.0被弃用,请参见pastebin示例函数(我知道最好在这里粘贴代码,但有很多…):

功能: 用法:


感谢所有帮助

正则表达式必须按顺序在字符串中移动。模式中的“regulat”之前有“nano”,但它们在测试字符串中交换。我不使用正则表达式来完成这项工作,而是坚持使用普通的旧字符串解析:

if (str.indexOf('nano') > -1) {
    if (str.indexOf('regulat') > -1 || str.indexOf('toxic') > -1
        || ((str.indexOf('risk') > - 1 || str.indexOf('hazard') > -1)
        && (str.indexOf('exposure') > -1 || str.indexOf('release') > -1)
    )) {
        /* all tests pass */
    }
}

如果您想实际捕获单词(例如,从“regulat”所在的位置获取“regulator”,我会将句子按分词分隔并检查单个单词。

单个正则表达式不是用于此的合适工具,IMO:

/^(?=.*\bnano)(?=(?:.*\bregulat|.*toxic|(?=.*(?:\brisk\b|\bhazard\b))(?=.*(?:\bexposure\b|\brelease\b))))/i.test(subject))
如果字符串满足您设定的条件,则返回True,但我发现嵌套的lookahead非常不可理解。如果JavaScript支持注释正则表达式,则如下所示:

nano* AND (regulat* OR *toxic* OR ((risk OR hazard) AND (exposure OR release)) )
^                 # Anchor search to start of string
(?=.*\bnano)      # Assert that the string contains a word that starts with nano
(?=               # AND assert that the string contains...
 (?:              #  either
  .*\bregulat     #   a word starting with regulat
 |                #  OR
  .*toxic         #   any word containing toxic
 |                #  OR
  (?=             #   assert that the string contains
   .*             #    any string
   (?:            #    followed by
    \brisk\b      #    the word risk
   |              #    OR
    \bhazard\b    #    the word hazard
   )              #    (end of inner OR alternation)
  )               #   (end of first AND condition)
  (?=             #   AND assert that the string contains
   .*             #    any string
   (?:            #    followed by
    \bexposure\b  #    the word exposure
   |              #    OR
    \brelease\b   #    the word release
   )              #    (end of inner OR alternation)
  )               #   (end of second AND condition)
 )                #  (end of outer OR alternation)
)                 # (end of lookahead assertion)
请注意,整个正则表达式由前瞻断言组成,因此匹配结果本身始终是空字符串

相反,您可以使用单个正则表达式:

if (/\bnano/i.test(str) &&
    ( 
        /\bregulat|toxic/i.test(str) ||
        ( 
            /\b(?:risk|hazard)\b/i.test(str) &&
            /\b(?:exposure|release)\b/i.test(str)
        )
    )
)    /* all tests pass */

您可能想试试。在您的示例字符串中,“nano”位于“regulatory”之后,但在您的正则表达式中,情况正好相反。这其中是否有任何预期的模式,即一个总是位于另一个之前?再举几个示例将有助于解释您的要求。@Barney-好建议,我就是这样得到的far@Chirag64-我是matchi的弦ng最初是来自此提要的推文:-因此,没有顺序,我们只是试图减少数量并增加相关性。@QL Studio:在这种情况下,恐怕您必须使用多个if条件和and&或,而不是尝试将所有内容都放在一个正则表达式中。@EP-请参阅上面的注释,我输入的字符串的顺序我的匹配和它的内容一样随机。。我只是尝试根据正则表达式对大量推文进行“筛选”-也许这是错误的方法?@QLStudio我的建议不适合吗?@EP-是的,对不起-你的解决方案解决了顺序问题。。但我仍然可以使用通配符(*)正常JS搜索中的字符?我需要匹配nano*(如nanotechnology)和regulat*(如regulation)
indexOf
使用字符集而不是单词。所以
“nanotechnology”。indexOf('nano')
返回
0
(大于
-1
)请解释一下[\b]-我读到了“\b是一个退格字符”,但我不确定这有什么关系?@QLStudio:在普通字符串中,
“\b”
确实是一个退格字符。在正则表达式中,
/\b/
(相当于
新正则表达式(“\\b”)
)是a。此锚匹配字母数字单词的开头或结尾。因此,
/\brisk\b/
仅匹配
“风险”
“存在风险!”
,而不匹配
“brisk”
“风险”“
。感谢您的解释-我已经离开了javasript,因为API的1.0版正在关闭,但是正则表达式应该可以像PHP中的一样工作-我想,当我把它全部修复好后,我会发布一个完整的答案。