如何讓這個正規表示式簡化?
P粉710454910
P粉710454910 2024-02-26 18:49:18
0
2
342

我有這個正規表示式:

"(WORD1.*WORD2.*WORD3)|(WORD1.*WORD3.*WORD2)|(WORD2.*WORD1.*WORD3)|(WORD2.*WORD3.*WORD1)|(WORD3.*WORD1. *WORD2)|(WORD3.*WORD2.*WORD1)"

它與這些單字相符:

WORD1WORD2WORD3
WORD1AWORD2BWORD3C
WORD3WORD1WORD2
WORD1WORD2WORD3WORD1

但不是這些話:

WORD1WORD1WORD2
WORD1AWORD1BWORD2C

當該正規表示式找到包含任意順序的3 個單字(WORD1WORD2WORD3)的字串時,它就會匹配。

我想用更多的單字做同樣的事情,但問題是正規表示式的大小隨著單字的數量呈指數增長。 是否可以簡化此正規表示式的構造方式來解決此問題(大小不會呈指數增長)?

P粉710454910
P粉710454910

全部回覆(2)
P粉663883862

簡單地迭代所有字串並過濾掉所有不包含所有關鍵字的字串:

(可以在下面的程式碼片段中找到更簡潔的版本)

function findMatch(strings, keywords) {
  const result = [];
  
  for (const string of strings) {
    if (keywords.every(keyword => string.includes(keyword))) {
      result.push(string);
    }
  }
  
  return result;
}

嘗試一下:

console.config({ maximize: true });

function findMatch(strings, keywords) {
  return strings.filter(
    string => keywords.every(keyword => string.includes(keyword))
  );
}

const testcases = [
  'WORD1WORD2WORD3',
  'WORD1AWORD2BWORD3C',
  'WORD3WORD1WORD2',
  'WORD1WORD2WORD3WORD1',
  'WORD1WORD1WORD2',
  'WORD1AWORD1BWORD2C'
];

const keywords = [
  'WORD1', 'WORD2', 'WORD3'
];

console.log(findMatch(testcases, keywords));
P粉998100648

您可以對每個單字使用正向前瞻。

/(?=.*WORD1)(?=.*WORD2)(?=.*WORD3).*/

下面的更高效能版本指定起始錨點,並且在驗證前瞻後僅符合單一字元。根據OP的要求,此技術僅適用於matching,而不適用於extraction

/^(?=.*WORD1)(?=.*WORD2)(?=.*WORD3)./

正向先行就像一個門,只有當括號內指定的匹配存在時,它才會繼續,但它不會消耗或捕獲它匹配的內容——它總是零長度。如果您「向前看」以查看每個單字前面是否存在 .*,那麼這些單字的順序並不重要。如果每個單字為真,則繼續進行,而不會使用任何內容進行配對。 p>

如果您只關心內容是否匹配,那麼兩個表達式之間唯一的實質差異就是它們花費的時間。假設您的內容中只有 3 個必需單字中的 2 個。除非解釋表達式的軟體能夠識別嘗試是徒勞的,否則它可能會在第一個位置查找三個單字“失敗”,然後在第二個位置嘗試“失敗”,等等,直到到達最後一個位置才放棄。透過指定^,只會在第一個位置進行檢查,節省了其他不必要檢查的時間。當您只是尋找內容中是否存在所有單字的真/假答案時,從末尾刪除 * 可以防止一些不必要的捕獲。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!