Wie kann ich diesen regulären Ausdruck einfacher machen?
P粉710454910
P粉710454910 2024-02-26 18:49:18
0
2
352

Ich habe diesen regulären Ausdruck:

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

Es passt zu diesen Wörtern:

WORD1WORD2WORD3
WORD1AWORD2BWORD3C
WORD3WORD1WORD2
WORD1WORD2WORD3WORD1

Aber nicht diese Worte:

WORD1WORD1WORD2
WORD1AWORD1BWORD2C

Dieser reguläre Ausdruck stimmt überein, wenn er eine Zeichenfolge findet, die 3 Wörter (WORD1WORD2WORD3) in beliebiger Reihenfolge enthält.

Ich möchte dasselbe mit mehr Wörtern machen, aber das Problem ist, dass die Größe des regulären Ausdrucks exponentiell mit der Anzahl der Wörter wächst. Ist es möglich, die Art und Weise, wie diese Regex aufgebaut ist, zu vereinfachen, um dieses Problem zu lösen (ohne exponentiell an Größe zuzunehmen)?

P粉710454910
P粉710454910

Antworte allen(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 个。除非解释表达式的软件能够识别尝试是徒劳的,否则它可能会在第一个位置查找三个单词“失败”,然后在第二个位置尝试“失败”,等等,直到到达最后一个位置才放弃。通过指定^,只会在第一个位置进行检查,节省了其他不必要检查的时间。当您只是寻找内容中是否存在所有单词的真/假答案时,从末尾删除 * 可以防止一些不必要的捕获。

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!