使用正则表达式查找链接文本

时间:2012-02-25 17:53:33

标签: c# javascript regex

小组:

我需要一些正则表达式的帮助。目标是能够识别用户可能在注释中表达链接的三种不同方式,具体如下。

<a href="http://www.msn.com">MSN</a>

可能性

    http://www.msn.com     OR
    https://www.msn.com    OR
    www.msn.com

然后,通过能够找到它们,我可以根据需要将它们中的每一个更改为真正的A标签。我意识到第一个例子已经是一个A标签,但我需要为我们的应用程序添加一些属性 - 比如TARGET和ONCLICK。

现在,我有正则表达式可以单独找到每个表达式,并且它们如下所示,分别与上面的示例相同。

<a?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*)/?>
(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?
[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?

但问题是我不能在字符串上运行所有这些因为第二个匹配第一个的一部分而第三个匹配第一个和第二个的一部分。无论如何 - 我需要能够清楚地找到三个排列,以便我可以单独替换它们中的每一个 - 因为第三个表达式例如需要添加http://。

我期待着每个人的帮助!

2 个答案:

答案 0 :(得分:1)

假设链接以空格或行的开头/结尾(或现有的A标记内)开始或结束,我想出了以下代码,其中还包含一些示例文本:

string regexPattern = "((?:<a (?:.*?)href=\")|^|\\s)((?:http[s]?://)?(?:\\S+)(?:\\.(?:\\S+?))+?)((?:\"(?:.*?)>(.*?)</a>)|\\s|$)";
string[] examples = new string[] {
    "some text <a href=\"http://www.msn.com/path/file?page=some.page&subpage=9#jump\">MSN</a>  more text",
    "some text http://www.msn.com/path/file?page=some.page&subpage=9#jump more text",
    "some text http://www.msn.com/path/file?page=some.page&subpage=9#jump more text",
    "some text https://www.msn.com/path/file?page=some.page&subpage=9#jump more text",
    "some text www.msn.com/path/file?page=some.page&subpage=9#jump",
    "www.msn.com/path/file?page=some.page&subpage=9#jump more text"
};

Regex re = new Regex(regexPattern);
foreach (string s in examples) {
    MatchCollection mc = re.Matches(s);
    foreach (Match m in mc) {
        string prePart = m.Groups[1].Value;
        string actualLink = m.Groups[2].Value;
        string postPart = m.Groups[3].Value;
        string linkText = m.Groups[4].Value;
        MessageBox.Show(" prePart: '" + prePart + "'\n actualLink: '" + actualLink + "'\n postPart: '" + postPart + "'\n linkText: '" + linkText + "'");
    }
}

由于此代码使用带数字的组,因此也可以在JavaScript中使用正则表达式。

根据您需要对现有A标记执行的操作,您还需要解析特定的第一个组。

<强>更新 根据请求修改了正则表达式,以便链接文本变为组号。 4

更新2: 为了更好地捕获格式错误的链接,您可以尝试修改此版本:

pattern = "((?:<a (?:.*?)href=\"?)|^|\\s)((?:http[s]?://)?(?:\\S+)(?:\.(?:[^>\"\\s]+))+)((?:\"?(?:.*?)>(.*?)</a>)|\\s|$)";

答案 1 :(得分:0)

好吧,如果我们想要一次性完成,你可以为每个场景创建名称组:

(?<full><a?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*)/?>.*</a>)|
(?<url>(http|https)://[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?)|
(<?www>[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?)

然后你必须检查哪个是匹配的组:

Match match = regex.Match(pattern);

if (match.Success)
{
    if (match.Groups["full"].Success) 
       Console.WriteLine(match.Groups["full"].Value);
    else if (match.Groups["url"].Success)
    ....
}