如何使用正则表达式从文本行中捕获 3 个不同的部分

Posted

技术标签:

【中文标题】如何使用正则表达式从文本行中捕获 3 个不同的部分【英文标题】:How to use regex to capture 3 different parts from text line 【发布时间】:2021-11-12 16:58:52 【问题描述】:
" john smith (idjs) <js@email.com>"

如何将前面的内容分成三部分?

1: john smith
2: (idjs)
3: <js@email.com>

我在尝试获取任何部件时遇到了麻烦:

试过这个:

var fullname = Regex.Match(item, $"(?=^).*(?=()").Value;

【问题讨论】:

我会使用拆分 那不会分开名字和姓氏 用“)”分割来获取邮件。用“(”分割以获得名称,并按顺序获得中间部分 【参考方案1】:

您可以为此使用named matched groups:

var item = " john smith (idjs) <js@email.com>";
String[] patternArr =

    "(?:\\s*)", 
    "(?<fullname>[a-zA-Z\\s]*?[a-zA-Z])", // captures the full name part
    "(?:\\s*)",
    "(?<idjs>\\([a-zA-Z]*\\))", // captures the idjs part
    "(?:.*)",
    "(?<email>(?:<).*@.*(?:>))" // captures the email part
;

var pattern = String.Join("", patternArr);
var m = Regex.Match(item, pattern);

if (m.Success)

    Console.WriteLine("fullname: 0", m.Groups["fullname"]);
    Console.WriteLine("idjs: 0", m.Groups["idjs"]);
    Console.WriteLine("email: 0", m.Groups["email"]);

输出:

fullname: john smith
idjs: (idjs)
email: <js@email.com>

演示:https://dotnetfiddle.net/y6U5j4

【讨论】:

你打败了我。现在我需要扔掉我几乎相同的代码。但是,我打算向 OP 建议两件事:1)考虑在解析过程中删除 idjs 部分周围的括号和电子邮件周围的尖括号,以及 2)有更好的电子邮件正则表达式浮动 - 偷一个其中 您将如何删除括号? @Rod 要去掉 idjs 周围的括号,您可以使用 ((?:\\()(?&lt;idjs&gt;[a-zA-Z]*)(?:\\))),要去掉 email 周围的尖括号,您可以改用 ((?:&lt;)(?&lt;email&gt;.*@.*)(?:&gt;)) (通过替换 patternArr) 中的相应行。 顺便说一句,我认为电子邮件条目是相当值得信赖的——因此我的“天真”电子邮件正则表达式。您当然可以选择/窃取适合您需求的正则表达式。例如。关于电子邮件验证,这将是一个更好的选择((?:&lt;)(?&lt;email&gt;\\S+@\\S+)(?:&gt;))MailAddress 类还为轻松验证电子邮件提供了很大帮助。进一步阅读:1 和 2【参考方案2】:
string pattern = 
    @"\s*" +       // zero or more whitespace characters
    @"(.*)" +      // any set of one or more characters
    @"\s+" +       // one or more whitespace characters
    @"(\(.*\))" +  // zero or more characters inside parens
    @"\s" +        // a single whitespace
    @"(<.*>)"      // zero or more characters inside brackets
    ;

请注意,Regex.Match().Value 不会为您提供部分 - 如果匹配,则仅提供整个字符串。你想要的是Regex.Match().Groups,它将返回一个GroupCollection,你可以遍历它来获取零件。

var groups = Regex.Match(item, pattern).Groups;
foreach(var group in groups)
    Console.WriteLine(groups);

【讨论】:

【参考方案3】:

虽然这不是通过使用正则表达式,但我会为此使用拆分:

    var input=" john smith (idjs) <js@email.com>";

    var first=input.Split('(');
    var second=first[1].Split(')');

    var name=first[0].Trim();
    var mid=second[0].Trim();
    var email=second[1].Trim();


/*
result:
john smith
idjs
<js@email.com>
*/

【讨论】:

以上是关于如何使用正则表达式从文本行中捕获 3 个不同的部分的主要内容,如果未能解决你的问题,请参考以下文章

使用 C++ 从文本行中提取字段和值

如何在 impala regexp_extract 方法中使用正则表达式 OR 运算符并获得不同的捕获组

正则表达式中分组功能高级用法

如何在我的 Django urls.py 中使用单个正则表达式捕获多个参数?

非捕获组不在正则表达式中工作

如何使用正则表达式捕获科学记数法中的减号?