正则表达式:另一种情况“匹配所有字符串除了一系列特定的字符串

时间:2013-09-16 19:23:04

标签: regex regex-negation

这个问题类似于我在网上和其他网站上发现的有关正则表达式的许多其他问题。但是,在尝试实现它们时,解决方案无效。这是由于我自己的无知,它不起作用,但我想得到以下的帮助:

我在做什么:

我正在努力将数据导入新数据库。大部分转换是在几个月前完成的,现在我需要转换所有新数据。

有关环境的一般资料:

要正确转换一个特定字段,我需要使用正则表达式。新数据库中的字段可以包含以下3个值中的任何一个:

- Kid
- No Mail
- Household

但是,源文件中的列有更多值,我想忽略它们。

导入程序具有创建“词典”的功能,可以将其应用于特定字段,以将导入的值转换为数据库中的标准值。这很适合修复常见的拼写错误等。

字典非常简单。您有一个正确值列表,每个正确的值可能有许多不正确的值。

例如:

    CORRECT VALUE           IMPORT VALUES
    Kid                     kid
                            kids
                            Child
                            Minor

在导入值列表中,您还可以输入正则表达式。

要解决的问题:

以下是字典文件的示例:

     CORRECT VALUE LIST     IMPORT VALUE
  -  Kid                    Kid
                            KID

  -  No Mail                No Mail
                            NO MAIL

  -  Household              HH

  -  OTHER                Regex expression to match: Anything else

实施例

输入值:

  • KID转换为Kid
  • HH转换为Household
  • John转换为OTHER
  • Do Not Call转换为OTHER
  • NO MAIL转换为No Mail
  • ABCD转换为OTHER

我做得太多了

这是我在网上找到并适应我的情况:

在codinghorror.com上找到的公式:

(?!kid|KID|Kid\b)\b\w+ - 这适用于'KID'但失败了                                           当我添加任何东西                                           其他由于某种原因

在stackoverflow.com上找到的公式:

^(?!kid$).* - 匹配所有内容 - 即使'孩子'

^((?!kid).)*$ - 相同

这是我第一次使用正则表达式,我只需要一些帮助即可开始使用它。

所以你可以给我任何帮助或指针。

谢谢!

2 个答案:

答案 0 :(得分:0)

我强烈建议您为导入的工作寻找不同的解决方案,因为这会非常快速地变得难以处理。但是,如果你真的想在这里建立一个至少按照你的要求建立一个正则表达式(如果我已经正确理解你,如果你的正则表达式引擎支持这个表单,你没有提到你正在使用的那个)。

(?!^(kid|KID|Kid|no mail)$).*

这样做^匹配字符串的开头和$字符串的结尾(或者有时是行的开头和结尾,但如果这些都是一行值,则无关紧要)。你可以用(?!)包装任何东西来表示“如果匹配则不匹配”和。*匹配任何东西。放|两种模式之间匹配这些模式。因此,如果中间的任何字符串被|分隔匹配并且之前或之后没有任何内容(这就是^和$的意思)然后(?!)内的位匹配,如果匹配则整个事物不匹配。如果第一位是正确的,则。*将匹配任何内容,因此整个匹配。

这就是你如何做到这一点,但确实考虑重新思考问题,因为几乎可以肯定的是你正在尝试做的更好的解决方案。祝你好运!

答案 1 :(得分:0)

简而言之,您有一个可能的输出值列表,并且对于每个这样的值,输入中的一组有限的可能值“匹配”它。看起来这些matches不区分大小写,但实际情况可能并非如此。

现在,任务很简单:对于每个输入字符串,尝试将其与此集匹配。如果它匹配特定模式,找出它属于哪个输出值 - 并将其放在结果集中。如果没有,请使用您设置的空白值(空字符串,据我所知)。

从理论到实践,这就是如何在JavaScript中实现这种方法:

// defining the dictionary: each key is a possible output value,
// each element is a list of matching words
var dictionary = {
    Kid:       ['kid', 'kids', 'child', 'minor'],
    'No Mail': ['no mail'],
    HouseHold: ['HH']
};
var defaultOutput = ''; // self-explanatory

// preparing the dictionary of patterns
var outputs = Object.keys(dictionary), 
    patternsToMatch = {};

outputs.forEach(function(outValue) {
    var alternationPart = dictionary[outValue].join('|');
    patternsToMatch[outValue] = new RegExp(
        '^(?:' + alternationPart + ')$', 'i');
});

// actually processing the inputs:
var testInputs = ['KiD', 'kidi', 'cHiLd', 'no mail', 'no email'];
console.log(testInputs);

var results = testInputs.map(function(inputStr) {
    var matchingOutput = defaultOutput;
    outputs.some(function(outputVal) {
        if (patternsToMatch[outputVal].test(inputStr)) {
            matchingOutput = outputVal;
        }
        return matchingOutput !== defaultOutput;
    });
    return matchingOutput;
});
console.log(results);

JS Fiddle

这很简单(并且有一些角落切割,其中包含上述区分大小写的问题),但(希望)显示了思考的方向。