正则表达式匹配除AND,OR和NOT之外的所有单词

时间:2016-01-07 13:19:19

标签: javascript regex

在我的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"]

但由于ü字边界,此字母与单词开头或结尾处的a-z字母表外的\b或任何其他字母不匹配。

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

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

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

1 个答案:

答案 0 :(得分:3)

这里的问题源于\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]|$)

捕获组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范围或非单词字符以外的字符。