6

かなり複雑なクエリに基づいて文字列のコレクションをフィルタリングする必要があります-「生の」形式では、次のようになります。

nano* AND (regulat* OR *toxic* OR ((risk OR hazard) AND (exposure OR release)) )

照合する文字列の 1 つの例:

Workshop on the Second Regulatory Review on Nanomaterials, 30 January 2013, Brussels

したがって、AND OR とワイルドカード文字を使用して一致させる必要があります。そのため、JavaScript で正規表現を使用する必要があると思います。

すべてが正しくループし、フィルタリングされ、一般的に機能していますが、正規表現が間違っていると100%確信しています-一部の結果が間違って省略されています-ここにあります:

/(nano[a-zA-Z])?(regulat[a-zA-Z]|[a-zA-Z]toxic[a-zA-Z]|((risk|hazard)*(exposure|release)))/i

どんな助けでも大歓迎です-この構文を理解するために心を正しく抽象化することは本当にできません!

アップデート:

正規表現が構築される順序の重要性を指摘する人はほとんどいませんが、検索されるテキスト文字列を制御できないため、順序に関係なく機能するソリューションを見つける必要があります。

アップデート:

Twitter API 1.0 の非推奨のため、最終的には PHP ソリューションを使用しました。関数の例については、pastebin を参照してください (ここにコードを貼り付けた方がよいことはわかっていますが、たくさんあります...):

関数: http://pastebin.com/MpWSGtHK 使い方: http://pastebin.com/pP2AHEvk

助けてくれてありがとう

4

2 に答える 2

24

単一の正規表現は、これに適したツールではありません.IMO:

/^(?=.*\bnano)(?=(?:.*\bregulat|.*toxic|(?=.*(?:\brisk\b|\bhazard\b))(?=.*(?:\bexposure\b|\brelease\b))))/i.test(subject))

文字列が指定した基準を満たす場合は Trueを返しますが、ネストされた先読みは非常に理解できないと思います。JavaScript がコメント付きの正規表現をサポートしている場合、次のようになります。

^                 # 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 */
于 2013-02-26T15:24:54.280 に答える
2

正規表現は文字列を順番に移動する必要があります。パターンの「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」の場所から「Regulatory」を取得する場合、文を単語区切りで分割し、個々の単語を調べます。

于 2013-02-26T14:06:16.850 に答える