簡體   English   中英

如何使用正則表達式提取 boolean 運算符后跟單詞直到下一個運算符?

[英]How to use regex to extract boolean operators followed by words until the next operator?

我正在嘗試組合一個相對簡單的表達式,用於從用戶輸入中提取 boolean 字符串運算符(AND、OR、NOT 等),這樣得到的匹配數組將包含單詞和前面的運算符,直到下一個運算符:

const query = 'lorem AND ipsum dolor OR fizz NOT buzz';

結果應該是這樣的:

[
 ['AND', 'ipsum dolor'],
 ['OR', 'fizz'],
 ['NOT', 'buzz']
]

我創建這個是為了在每個運算符之后獲取單個單詞,這很好:

^(\w+\s?)+?|(AND) (\w+)|(OR) (\w+)|(NOT) (\w+)

然后嘗試修改它以處理運算符后的多個單詞以獲得上述結果,但它總是貪婪並捕獲整個字符串輸入:

(AND|OR|NOT) (\w+\s?)+ (?:AND|OR|NOT)

更新

我已經弄明白了,但我不確定它有多漂亮或有效率:

^(\w+)|(AND|OR|NOT) (.*?(?= AND|OR|NOT))|(AND|OR|NOT) .*?$

您還可以使用否定前瞻來斷言 so 之后的單詞字符不以任何一個備選方案開頭

\b(AND|OR|NOT) ((?!AND|OR|NOT)\b\w+(?: (?!AND|OR|NOT)\w+)*)

正則表達式演示

 const regex = /\b(AND|OR|NOT) ((??AND|OR|NOT)\b\w+(:? (;;AND|OR|NOT)\w+)*)/gm; const str = `lorem AND ipsum dolor OR fizz NOT buzz`; let m. let result = []. while ((m = regex,exec(str));== null) { result.push([m[1]; m[2]]); } console.log(result);

我無法使用正則表達式來做到這一點,但這是一個可以工作的超級簡單的解決方案。

let q = 'lorem AND ipsum dolor OR fizz NOT buzz';
let special = ['AND', 'OR', 'NOT'];

let fullResult = [];
let skip = true;

q.split(' ').forEach( word => {
    if ( special.indexOf(word) !== -1 ) {
        fullResult.push([word]);
        skip = false;
    } else if (!skip){
        fullResult[fullResult.length-1].push(word);
    }
});

console.log(fullResult);

我不認為你可以在 JavaScript 中純粹使用正則表達式到達那里,但你可以非常接近:

 const query = 'lorem AND ipsum dolor OR fizz NOT buzz'; const rex = /\b(AND|OR|NOT|NEAR)\b\s*(.*?)\s*(?=$|\b(?:AND|OR|NOT|NEAR)\b)/ig; const result = [...query.matchAll(rex)].map(([_, op, text]) => [op, text]); console.log(result);

正則表達式/\b(AND|OR|NOT|NEAR)\b\s*(.*?)\s*(?=$|\b(?:AND|OR|NOT|NEAR)\b)/ig尋找:

  • 斷言
  • 您的一名操作員(捕獲它)
  • 斷言
  • 零個或多個空白字符(捕獲它們)
  • 任何事物的非貪婪匹配
  • 零個或多個空白字符
  • 另一個運算符或字符串的末尾

map調用之后的matchAll只是用於刪除初始數組條目(具有匹配全文的條目)。 我已經用解構完成了,但你可以改用slice

const result = [...query.matchAll(rex)].map(match => match.slice(1));

 const query = 'lorem AND ipsum dolor OR fizz NOT buzz'; const rex = /\b(AND|OR|NOT|NEAR)\b\s*(.*?)\s*(?=$|\b(?:AND|OR|NOT|NEAR)\b)/ig; const result = [...query.matchAll(rex)].map(match => match.slice(1)); console.log(result);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM