【问题标题】:JavaScript find if string has a substring that matches a given reg expJavaScript 查找字符串是否具有与给定正则表达式匹配的子字符串
【发布时间】:2016-09-27 16:19:44
【问题描述】:
var str = "4/16/14, 10:24 AM - John Doe: How is everything going on? Check this: iPhone7!"

我想检查字符串是否包含与AM - <some-name>: 匹配的子字符串。例如,在上面的字符串中,它应该匹配AM - John Doe: 并返回John Doe。 (当然,一旦匹配,我可以使用子字符串获取名称)。此外,有时AM - John Doe: 中可能会有特殊字符而不是空格。正则表达式在这种情况下也应该起作用。

例如:

var str1 = "4/16/14, 10:24 AM - John Doe likes your photo";
var str2 = "4/16/14, 10:24 AM John Doe replied to your comment";
var str3 = "4/16/14, 10:24 AM John Doe: Whats going on";
var str4 = "4/16/14, 10:24 AM John Doe: Whats going on : hmmm";

正则表达式应该匹配 str3str4,因为它包含一个以 AM 开头的子字符串并以第一个 :

结尾

对于 str3 和 str4,我想取名为 John Doe。 注意:str1 和 str2 也有 John Doe,但它不会立即跟随 :

我尝试过的表达方式:

str.match(/[AP]M - \w+[ ]?\w+[ ]?\w+:./);

当有特殊字符(例如 UTF-8 字符)时,上述方法会失败。不可见,但似乎有 e2 80 80 等字符。

【问题讨论】:

标签: javascript string


【解决方案1】:

您可以使用/\b[AP]M\W+(?:-\W+)?([^:]+):/

var str1 = "4/16/14, 10:24 AM - John Doe likes your photo";
var str2 = "4/16/14, 10:24 AM John Doe replied to your comment";
var str3 = "4/16/14, 10:24 AM John Doe: Whats going on";
var str4 = "4/16/14, 10:24 AM John Doe: Whats going on : hmmm";
var ss = [ str1, str2, str3, str4 ]; // Test strings
var rx = /\b[AP]M\W+(?:-\W+)?([^:]+):/; 
for (var s = 0; s < ss.length; s++) {                  // Demo
  document.body.innerHTML += "Testing \"<i>" + ss[s] + "</i>\"... ";
  document.body.innerHTML += "Matched: <b>" + ((m = ss[s].match(rx)) ? m[1] : "NONE") + "</b><br/>";
}

模式详情

  • \b - 单词边界
  • [AP]M - AMPM
  • \W+ - 1+ 非单词字符
  • (?:-\W+)? - 连字符和非单词字符的可选序列
  • ([^:]+) - 第 1 组(我们的输出)捕获除 : 之外的一个或多个字符
  • : - 冒号。

由于[^...] 是一个否定字符类,它将匹配任何 个字符直到第一个:(不包括匹配中的:),但是模式中尾随的: 实际上要求字符串中存在:

【讨论】:

  • 太棒了。我已经尝试了几个小时。这行得通!非常感谢。
  • 其实没有。 str1 失败。它匹配了它不应该有的 str1,因为 str1 没有任何尾随“:”
  • 那么,你现在的模式是什么?匹配"AM/PM - "之后的所有大写单词?可以有 Unicode 字母吗,比如Сергей Макаров
  • var str = "2014 年 4 月 16 日上午 10:24 - John Doe 一切进展如何?检查这个 iPhone7!"上面的 exp 匹配这个 str。它不应该,因为在 Doe 之后没有尾随“:”
  • 你在问题​​中提到的符号是U+2000, EN QUAD。会计。对于 MDN,\s 匹配 [ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​-\u200a​\u2028\u2029\u202f\u205f​\u3000\ufeff]。我认为/\b[AP]M\s+(?:-\s+)?([^:]+):/ 应该适合你。如果没有,请尝试我目前的答案。
【解决方案2】:

我用你的正则表达式做了一个例子,它可以捕获特殊字符,你可以找到here

正如我所说,我通过修改它来使用你的正则表达式:

[AP]M[^a-zA-Z]-[^a-zA-Z]\w+[ ]?\w+[ ]?\w+:.

如果您还想排除数字,可以这样修改:

[AP]M[^a-zA-Z\d]-[^a-zA-Z\d]\w+[ ]?\w+[ ]?\w+:.

此外,如果您希望名称中有特殊字符,您可以使用 \S 而不是 \w,这将包括除空白字符之外的所有内容。 那么正则表达式将是这样的:

[AP]M[^a-zA-Z]-[^a-zA-Z]\S+[ ]?\S+[ ]?\S+:.

我已经更新了 Regex101 示例。

【讨论】:

  • 这种黑名单方法有些脆弱。如果- 周围有空格,则[^a-zA-Z\d] 没有帮助,因为\s 已经足够了。说到\w,如果名字是Łukasz Sącz呢?那就不匹配了。
  • 我想证明你错了。首先 \s 是不够的,因为问题是" Also, Sometimes there maybe special characters instead of white spaces in AM - John Doe:. Regular expression should work in this case also."。因此 \s 根本不够。此外,如果您使用 [\S] 代替,您还将捕获任何 a-z 字符。整个正则表达式的重点是捕捉- 周围的特殊字符和空格。
猜你喜欢
  • 2015-06-15
  • 2019-07-10
  • 2022-01-17
  • 2023-02-04
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
相关资源
最近更新 更多