【问题标题】:How to filter URLs and phone numbers from text except if they start with ***如何从文本中过滤 URL 和电话号码,除非它们以 *** 开头
【发布时间】:2017-05-24 04:50:47
【问题描述】:

我在 C# 中使用正则表达式来过滤文本中的所有 URL 和电话号码时遇到问题,除非它们以 *** 开头。如果更容易,星星也可以是其他角色。 例如,排除过滤以 ! 开头的 URL。或在 [] 内。

我正在使用 regex.Replace(text, replacement) 方法。

var rgx = new Regex(pattern, RegexOptions.IgnoreCase);
rgx.Replace(str, replacement ?? "[ URL HIDDEN ]");

所以我设法通过以下方式处理电子邮件:

\b(?<!(\*\*\*))[A-Z0-9._%+\*-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b


我当前用于过滤 URL 的正则表达式:

\b((https?:\/\/(www\.)?)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}[-a-zA-Z0-9@:%_\+.~#?&\/=]*)

我目前用于过滤电话号码的正则表达式:

\+?[0-9]{0,4}[\.\-\/)( ]*[0-9]{3,4}[\.\-\/)( ]*[0-9]{3,4}[\.\-\/)( ]*[0-9]{3,4}(?![a-z]{1,4})


我尝试过使用前瞻和后瞻的多种变体,但找不到解决方案。

感谢所有帮助。此外,如果您有任何其他更好的建议或解决方案,我将不胜感激。

【问题讨论】:

  • 你在Regex.IsMatch里面使用它吗?请展示你如何使用这些模式。
  • 我修改了我的答案。我目前正在使用替换方法。
  • 好的,我会建议一些非常通用的东西。

标签: c# regex


【解决方案1】:

由于 URL 尤其是电话模式包含可选部分,甚至可能包含空格,因此单纯的后视是行不通的,或者至少您必须添加几个后视,这会使模式变得笨拙。

我建议使用一种通用方法:匹配并捕获您需要保留的内容,并仅匹配您需要替换的内容。

使用 2 个备选方案动态构建模式:第一个匹配并捕获以 *** 开头的模式,另一个未包含在捕获组中。在 match evaluator 中,检查 Group 1 是否匹配,如果是,则保留,否则替换匹配:

var rxUrl = @"\b(https?://(www\.)?)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}[-a-zA-Z0-9@:%_+.~#?&/=]*";
var rxPhone = @"\+?[0-9]{0,4}(?:[-./() ]*[0-9]{3,4}){3}(?![a-z]{1,4})";
var rxEmail = @"(?i)\b[A-Z0-9._%+*-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b";
var s = "abc@email.com ***abc@email.com +22 345 456 678 ***+22 345 456 678 http://eee.tt ***http://eee.tt";
var res = Regex.Replace(s, $@"(\*{{3}}{rxUrl})|{rxUrl}", m => m.Groups[1].Success ? m.Value : "[ URL HIDDEN ]");
res = Regex.Replace(res, $@"(\*{{3}}{rxPhone})|{rxPhone}", m => m.Groups[1].Success ? m.Value : "[ PHONE HIDDEN ]");
res = Regex.Replace(res, $@"(\*{{3}}{rxEmail})|{rxEmail}", m => m.Groups[1].Success ? m.Value : "[ EMAIL HIDDEN ]");
Console.WriteLine(res);
// => [ URL HIDDEN ] ***abc@email.com [ PHONE HIDDEN ] ***+22 345 456 678 [ URL HIDDEN ] ***http://eee.tt

请参阅C# demo online

The Best Regex Trick Ever

【讨论】:

  • 如果您还需要替换前面带有 3 个以上星号的匹配项,则需要使用 (?&lt;!\*)\*{3} 而不仅仅是 \*{3}
  • 谢谢。我将实施并测试它。会让你知道的。
【解决方案2】:

您可以使用正则表达式进行过滤,也可以使用以下内容对其进行迭代:

List<string> origins = new List<string> { "Do I really start with stars?", "***How about me, do I start with stars?" };
foreach (string item in origins)
{
    if (item.StartsWith("***"))
    {
    Console.WriteLine("item " + item + " starts with ***");
    }
    else
    {
    Console.WriteLine("item " + item + " does NOT start with ***");
    }
}
Console.ReadLine();

在非常低的级别使用正则表达式:^[^*]{3,3}.*

***123-456-7890 (does not qualify)
123-456-7890 (does qualify)
http://blahblahblah.com (does qualify)
***http://blahblahblah.com (does not qualify)

【讨论】:

  • 谢谢。但我不明白如何将其应用于从文本中查找和过滤特定内容...电子邮件、网址和电话号码
  • origins 将被您用来获取链接、电子邮件和电话号码的任何内容填充。一旦 'origins' 具有值,您就可以检查这些值并对其采取行动。
猜你喜欢
  • 1970-01-01
  • 2019-11-03
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 2011-12-07
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多