我在C#中有一个正则表达式来检测文本中的电子邮件,然后我在其中放入一个带有mailto参数的锚标记,以使其可以点击。但是,如果电子邮件已经在锚标记中,则正则表达式会检测锚标记中的电子邮件,然后下一个代码会在其上添加另一个锚标记。 Regex有没有办法避免已经在锚标签中的电子邮件?
C#中的正则表达式代码是:
string sRegex = @"([\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?)";
Regex Regx = new Regex(sRegex, RegexOptions.IgnoreCase);
,示例文本为:
string sContent = "ttt <a href='mailto:someone@example.com'>someemail@mail.com</a> abc email@email.com";
,所需的输出是:
"ttt <a href='mailto:someone@example.com'>someemail@mail.com</a> abc <a href='mailto:email@email.com'>email@email.com</a>";
所以,这里的重点是Regex应该只检测那些不在锚标签内或已经可点击的有效电子邮件,并且它们都不应该是锚标签中锚标记的href值。
上面给出的Regex正在检测文本中不需要的每个可能的电子邮件。
答案 0 :(得分:4)
你可以使用负面看来测试mailto:
(?<!mailto\:)([\w-]+(.[\w-]+)@([a-z0-9-]+(.[a-z0-9-]+)?.[a-z]{2,6}|(\d{1,3}.){3}\d{1,3})(:\d{4})?)
应匹配前面没有mailto:
我认为正在发生的事情是.
中的([\w\-]+(.[\w-])+)
匹配太多了。您的意思是使用.
而不是\.
吗?
通过转义.
以下代码生成
someemail@mail.com
email@email.com
public void Test()
{
Regex pattern = new Regex(@"\b(?<!mailto:)([\w\-]+(\.[\w\-])*@([a-z0-9-]+(.[a-z0-9-]+)?.[a-z]{2,6}|(\d{1,3}.){3}\d{1,3})(:\d{4})?)");
MatchCollection matchCollection = pattern.Matches("ttt <a href='mailto:someone@example.com'>someemail@mail.com</a> abc email@email.com");
foreach (Match match in matchCollection)
{
Debug.WriteLine(match);
}
}
您尝试做的事情的现实实施可能看起来更像
Regex pattern = new Regex(@"(?<!mailto\:)\b[\w\-]+@[a-z0-9-]+(\.[a-z0-9\-])*\.[a-z]{2,8}\b(?!\<\/a)");
MatchCollection matchCollection = pattern.Matches("ttt <a href='mailto:so1meone@example.com'>someemail@mail.com</a> abc email@email.com");
foreach (Match match in matchCollection)
{
Debug.WriteLine(match);
}
对不起,你是对的,我没有认为否定的断言不够贪婪。
\b(?!mailto\:)([\w-]+(.[\w-]+)@([a-z0-9-]+(.[a-z0-9-]+)?.[a-z]{2,6}|(\d{1,3}.){3}\d{1,3})(:\d{4})?)
应该有效