正则表达式忽略空href

时间:2014-03-11 18:45:10

标签: c# html regex

我编写了一个函数来替换href的值与某些值+原始href

说: -

<a href="/somepage.htm" id="test">

替换为

<a href="http//www.stackoverflow.com/somepage.htm" id="test">

无需更换的地方: -

<a href="http//www.stackoverflow.com/somepage.htm" id="test">
 <a href="#" id="test">
<a href="javascript:alert('test');" id="test">
<a href="" id="test">

我编写了以下方法,处理了所有案例,但没有使用空白值href

public static string RelativeToAbsoluteURLS(string text, string absoluteUrl, string pattern = "src|href")
    {
        if (String.IsNullOrEmpty(text))
        {
            return text;
        }
        String value = Regex.Replace(text, "<(.*?)(" + pattern + ")=\"(?!http|javascript|#)(.*?)\"(.*?)>", "<$1$2=\"" + absoluteUrl + "$3\"$4>", RegexOptions.IgnoreCase | RegexOptions.Multiline);

        return value.Replace(absoluteUrl + "/", absoluteUrl);
    }

?!http|javascript|#忽略http, javascript, #,因此它适用于这些情况,但如果我们考虑遵循部分

(?!http|javascript|#)(.*?)

并将此*替换为+

(?!http|javascript|#)(.+?)

它不适用于空箱。

2 个答案:

答案 0 :(得分:1)

*更改为+不起作用,因为您完全错了:

  • *表示&#34;零或更多&#34;
  • +表示&#34;一个或多个&#34;

因此,对于+,您强制要求内容 ,而不是允许内容丢失。

你错的另一件事是安置。该地点的*是指.。它们一起表示零个或多个字符&#34;。因此,此部分已经不需要任何内容。因此,由于您的正则表达式目前不适用于null内容,因此其他似乎需要这样做。

查看前面的表达式:

(?!http|javascript|#)(.*?)

?!是一个零宽度的负向前瞻。零宽度。负。这意味着它也不需要任何内容​​。

所以,我收到了你的代码,将其粘贴到the online compiler,然后我用你的例子<a href="" id="test">提供了它:

使用System.IO; 使用系统; 使用System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        string text = "<a href=\"\" id=\"test\">";
        string pattern = "src|href";
        string absoluteUrl = "YADA";
        string value = Regex.Replace(text, "<(.*?)(" + pattern + ")=\"(?!http|javascript|#)(.*?)\"(.*?)>", "<$1$2=\"" + absoluteUrl + "$3\"$4>", RegexOptions.IgnoreCase | RegexOptions.Multiline);

        Console.WriteLine(value);
    }
}

并猜测它的作用:

Compiling the source code....
$mcs main.cs -out:demo.exe 2>&1

Executing the program....
$mono demo.exe 
<a href="YADA" id="test">

所以,你要么说实话,要么你在这里发布时更改了代码,或者你的代码中有其他东西搞砸了,抱歉。

编辑:

所以,事实证明,href =&#34;&#34;本来应该被忽略。

然后最简单的事情是你可以添加另一个负面预测,它将明确地阻止href=""个案。但请注意,该组的位置将有所不同。当前组在href的引号内,所以它不能&#34; peek&#34;整个href-quotes是怎样的。新组必须在引号之前。

"<(.*?)(" + pattern + ")=(?!\"\")\"(?!http|javascript|#)(.*?)\"(.*?)>"

请注意,就在href的第一个引用之前,我已经添加了一个(?!\"\"),这将确保&#34;不会出现引用跟随引号的情况&#34;。< / p>

答案 1 :(得分:0)

我知道你要求RegEx。

但是这里有另一种选择,因为我认为使用Uri.IsWellFormedUriString是值得的。 这样你也可以重用helper函数:

public string RelativeToAbsoluteURLS(string text, string absoluteUrl, string pattern = "src|href")
{
    if (isHrefRelativeURIPath(text)){
        text = absoluteUrl + "/" + System.Text.RegularExpressions.Regex.Replace("///days/hours.htm", @"^\/+", "");
    }

    return text;
}

public bool isHrefRelativeURIPath(string value) {
    if (isLink(value) ||
        value.StartsWith("#") ||
        value.StartsWith("javascript"))
    {
        return false;
    }

    // Others Custom exclusions

    return true;
}


public bool isLink(string value) {
    if (String.IsNullOrEmpty(value))
        return false;

    return Uri.IsWellFormedUriString("http://" + value, UriKind.Absolute);
}