【问题标题】:regex to match all words but AND, OR and NOT正则表达式匹配除 AND、OR 和 NOT 之外的所有单词
【发布时间】:2026-01-31 10:10:01
【问题描述】:

在我的 javascript 应用程序中,我有这个随机字符串:

büert AND NOT 3454jhadf üasdfsdf OR technüology AND (bar OR bas)

我想匹配除单词ANDORNOT 之外的所有单词特殊字符和数字。

我试过是这个

/(?!AND|OR|NOT)\b[\u00C0-\u017F\w\d]+/gi
这导致
["büert", "3454jhadf", "asdfsdf", "technüology", "bar", "bas"]

但由于\b 字的边界,这个字与字首或字尾的ü 或a-z 字母表之外的任何其他字母不匹配。

删除 \b 奇怪地结束了匹配部分或我想排除的单词:

/(?!AND|OR|NOT)[\u00C0-\u017F\w\d]+/gi
结果是
["büert", "ND", "OT", "3454jhadf", "üasdfsdf", "R", "technüology", "ND", "bar", "R", "bas"]

除了我想要排除的字符之外,匹配所有单词的正确方法是什么,无论它们包含什么类型的字符?

【问题讨论】:

标签: javascript regex


【解决方案1】:

这里的问题根源在于 \b(以及 \w 和其他速记类)在 JavaScript 中不支持 Unicode。

现在,有两种方法可以实现您想要的。

1。用你想丢弃的模式分割

var re = /\s*\b(?:AND|OR|NOT)\b\s*|[()]/;
var s = "büert AND NOT 3454jhadf üasdfsdf OR technüology AND (bar OR bas)";
var res = s.split(re).filter(Boolean);
document.body.innerHTML += JSON.stringify(res, 0, 4);
// = > [ "büert", "3454jhadf üasdfsdf", "technüology", "bar", "bas" ]

注意使用非捕获组(?:...),以免将不需要的单词包含到结果数组中。此外,您需要将所有标点符号和其他不需要的字符添加到字符类中。

2。使用自定义边界进行匹配

您可以在正则表达式中使用带有锚点/反向否定字符类的分组,如下所示:

(^|[^\u00C0-\u017F\w])(?!(?:AND|OR|NOT)(?=[^\u00C0-\u017F\w]|$))([\u00C0-\u017F\w]+)(?=[^\u00C0-\u017F\w]|$)

capure group 2 将保存您需要的值。

regex demo

JS代码演示:

var re = /(^|[^\u00C0-\u017F\w])(?!(?:AND|OR|NOT)(?=[^\u00C0-\u017F\w]|$))([\u00C0-\u017F\w]+)(?=[^\u00C0-\u017F\w]|$)/gi; 
var str = 'büert AND NOT 3454jhadf üasdfsdf OR technüology AND (bar OR bas)';
var m;
var arr = []; 
while ((m = re.exec(str)) !== null) {
  arr.push(m[2]);
}
document.body.innerHTML += JSON.stringify(arr);

或使用块动态构建正则表达式:

var bndry = "[^\\u00C0-\\u017F\\w]";
var re = RegExp("(^|" + bndry + ")" +                   // starting boundary
           "(?!(?:AND|OR|NOT)(?=" + bndry + "|$))" +    // restriction
           "([\\u00C0-\\u017F\\w]+)" +                  // match and capture our string
           "(?=" + bndry + "|$)"                        // set trailing boundary
           , "g"); 
var str = 'büert AND NOT 3454jhadf üasdfsdf OR technüology AND (bar OR bas)';
var m, arr = []; 
while ((m = re.exec(str)) !== null) {
  arr.push(m[2]);
}
document.body.innerHTML += JSON.stringify(arr);

说明:

  • (^|[^\u00C0-\u017F\w]) - 我们的自定义边界(匹配以^ 开头的字符串或[\u00C0-\u017F\w] 范围之外的任何字符)
  • (?!(?:AND|OR|NOT)(?=[^\u00C0-\u017F\w]|$)) - 匹配限制:如果有ANDORNOT 后跟字符串结尾或\u00C0-\u017F 范围以外的字符或非单词字符,则匹配失败李>
  • ([\u00C0-\u017F\w]+) - 匹配单词字符 ([a-zA-Z0-9_]) 或来自 \u00C0-\u017F 范围的字符
  • (?=[^\u00C0-\u017F\w]|$) - 尾随边界,可以是字符串结尾 ($) 或 \u00C0-\u017F 范围以外的字符或非单词字符。

【讨论】:

  • 由于限制跳过 AND/OR/NOT,这看起来不可读。也许,您可以使用块来动态构建 RegExp 以使其更具可读性。
  • 我觉得这个正则表达式太复杂了,你应该添加split解决方案。
  • 或者作为骗子关闭。这两种解决方案之间仍然存在差异。虽然这个正则表达式看起来很怪异,但它实际上是在 JS 中定义自定义边界的一种有效方式。
最近更新 更多