匹配字符串,除非以字符开头和结尾

时间:2019-02-12 19:26:17

标签: javascript regex

我正在尝试在JavaScript中使用正则表达式来确定是否删除邮件。如果邮件中的任何地方都包含“字符串”,除非要用冒号将其包围,否则我想删除该邮件。

  • string-被删除
  • blah string-被删除
  • :string blah-被删除
  • :string: string-被删除
  • thing :string:-不会被删除

我正在使用JavaScript,到目前为止,我正在使用message.match(/string/i)来查看消息是否被删除。我已经尝试过否定的前瞻,但我可能用错了。

编辑:很抱歉不包括此内容,但是:blahstring::stringblah::blahstringblah:也不应删除。

5 个答案:

答案 0 :(得分:4)

如果支持向后看,则可以使用

/(?<!:(?=string:))string/i

请参见regex demo

详细信息

  • (?<!:(?=string:))-如果紧接当前位置左侧的:紧随其后的是string:
  • ,则负匹配将使匹配失败
  • string-一个string

var strs = ['string - gets deleted','blah string - gets deleted',':string blah - gets deleted',':string: string - gets deleted','thing :string: - doesnt get deleted'];
var rx = /(?<!:(?=string:))string/i;
for (var s of strs) {
  console.log(s, "=>", rx.test(s));
}

输出:

string - gets deleted => true
blah string - gets deleted => true
:string blah - gets deleted => true
:string: string - gets deleted => true
thing :string: - doesnt get deleted => false

无后顾之忧的版本

它基于匹配string的正则表达式,其中不带冒号或两侧都带有冒号。如果匹配项至少包含一个匹配项,且开头没有冒号,则必须删除该条目。

var strs = ['string - gets deleted','blah string - gets deleted',':string blah - gets deleted',':string: string - gets deleted','thing :string: - doesnt get deleted'];
var rx = /(?::(?=string:))?string/gi;
for (var s of strs) {
  var matches = s.match(rx);
  console.log(s, "=>", (matches.some(function (x) { return !/^:/.test(x); }) ));
}

答案 1 :(得分:4)

在某些边界情况下,冒号仅出现在“字符串”的一侧。因此,我认为删除所有出现的“:string:”会更容易,然后再查找“ string”的匹配项:

function deleteIt(msg) {
    return /string/i.test(msg.replace(/:\w*string\w*(?=:)/ig, ":"));
}

console.log(deleteIt("this is :string ")); // true
console.log(deleteIt("this is string: ")); // true
console.log(deleteIt("string:string: ")); // true
console.log(deleteIt("this is :string: ")); // false
console.log(deleteIt("this is :blastring:stringbla:string: ")); // false

以上代码段中的最后一个测试是一个特例。冒号由前面和后面的“字符串”“共享”。根据您是否希望忽略此类“字符串”出现,您可能需要用正常捕获第二个冒号来代替前瞻。

附录

在对问题的编辑中,您说“:blastring:”或“:stringbla:”也不应触发删除。

因此,我在上面的正则表达式中两次添加了\w*以符合该额外要求。

如果冒号和“字符串”之间也允许使用标点符号或其他非字母字符,例如“:,-°string ^ 0&:”(不是空格),则使用\S*代替\w*

答案 2 :(得分:1)

您可以结合使用正向后看和负向前看:

(?<=^|[^:]|(:))string(?!\1)

演示:https://regex101.com/r/Ca1TTW/1

答案 3 :(得分:1)

这对我的测试有效:^.*(?<!\:)string(?!\:).*$

  • ^匹配字符串的开头
  • .*多次匹配任何字符
  • (?<!\:)如果缺少:后缀则匹配
  • string匹配单词string
  • (?!\:)如果缺少后缀则匹配
  • .*多次匹配任何字符
  • $匹配行尾

答案 4 :(得分:0)

尝试

let s=[ "string",
        "blah string",
        ":string blah",
        ":string: string",
        "thing :string:",
        ":blahstring:",
        ":stringblah:",
        ":blahstringblah:",
      ];

let d=s.filter(x=> !x.match(/:.*string.*:/i) || x.match(/:.*string.*:.*string.*/i) || x.match(/.*string.*:.*string.*:/i));

console.log('Delete :', d);
console.log('Save   :', s.filter(x=>!d.includes(x)) );

我们将“删除列表” d元素放入其中

  • !x.match(/:string:/i)-不包含:string:
  • x.match(/:.*string.*:.*string.*/i)包含:string:,然后包含string以外的:
  • x.match(/.*string.*:.*string.*:/i)与上述相同,反之亦然