当前位置:编程学习 > C#/ASP.NET >>

求。给文章关键字加链接函数。非常复杂

现在网站经常要给文章里的关键字自动加链接。。所在这里就涉及 

到给指定关键字加链接,替换字符串问题 


如我的文章为: 


str1 = "我想学习c语言教程,我想看的是C语言视频教程,其它什 

么C语言教程,我都不想看。我喜欢C语言" 


我要替换的关键字数组为: 

a1 ={c语言视频教程,C语言教程,c语言}; 

对应网址数组为:

a2 ={a1.html,a2.html,a3.html}; 




替换加链接的关键字规则如下: 

1.只替换第一次匹配的关键字,给其增加链接,即使其被 <a>标签包含着,且A标签中有title属性,title属性的值就是被匹配关键字 

2.虽然匹配,但该被匹配的字符串,被 <a>标签包含着,或是a标签中的title属性的值,则跳过, (这个非常重要,不管是字符串本身就包括链接,还是后来被前期替换而包含链接的,总是只要关键字被<A>包含着,就跳过)

3.我用的是vs2003,所以有很多朋友写的都用不了。在这里再次谢谢过客,及Sandy945,虽然因为我是1.1的用不了,但还是万分感谢。



希望最后替换后的结果为: 

str1 = “我想习学 <a href="http://www.21shipin.com" target="_blank" title="C语言教程">c语言教程 </a>,我想看的是 <a href="http://www.21shipin.com" target="_blank" title="C语言视频教程">C语言视频教程 </a>,其它什么 <a href="http://www.21shipin.com" target="_blank" title="C语言">C语言 </a>教程,我都不想看。我喜欢C语言” 


请问这个功能怎么实现。。。求教了。。 


最好写成一下函数。。头痛。为这个弄一半个月了。。。 
--------------------编程问答-------------------- 使用ArrayList或Hashtable一样使用
--------------------编程问答-------------------- ArrayList或Hashtable --------------------编程问答-------------------- ArrayList或Hashtable

同意 --------------------编程问答-------------------- 用正则会比较容易,而且你这个还要注意顺序;
{c语言、C语言教程、c语言视频教程},这样的顺序,反过来你会看到不希望的结果,因为满足“c语言视频教程”这个条件的同时满足前面两个条件。
string str="c语言、C语言教程、c语言视频教程";
当然不用正则也可以。
str=str.ReplaceAll("c语言","<a href=\"http://www.21shipin.com\" target=\"_blank\" title=\"C语言\">C语言 </a>");

str=str.ReplaceAll("C语言教程","<a href=\"http://www.21shipin.com\" target=\"_blank\" title=\"C语言教程\">C语言教程 </a>");

str=str.ReplaceAll("C语言视频教程","<a href=\"http://www.21shipin.com\" target=\"_blank\" title=\"C语言视频教程\">C语言视频教程 </a>教"); --------------------编程问答-------------------- 为了提高效率,建议使用StringBuilder,可以用一个类建议源字符串和替换字符串的映射关系,然后用List<T>保存所有可能集合。 --------------------编程问答-------------------- ArrayList 用这个吧,2003里这个很好用的 --------------------编程问答-------------------- 已经好些年不用VS2003了,现在也不搞开发,哪些支持哪些不支持也记得不是很清楚了
VS2003中匿名方法不支持,但好像委托还是支持的,这样试下吧

         //替换方法 
         private string keyAddUrl(string src, ArrayList keys)
        {
            Regex reg = new Regex(@"(?i)(?:^|(?<!<a\b(?>[^<>]*))>)(?>[^<>]*)(?:<|$)");
            return reg.Replace(src, new MatchEvaluator(replaceKey));
        }

        int length = 0;
        string temp = string.Empty;        
        ArrayList keys = new ArrayList(new string[] { "c语言", "C语言教程", "c语言视频教程" });
        private string replaceKey(Match m)
        {
            temp = m.Value;
            length = temp.Length;
            for (int i = keys.Count - 1; i >= 0; i--)
            {
                temp = Regex.Replace(temp, @"(?is)^((?:(?:(?!" + Regex.Escape(keys[i].ToString()) + @"|</?a\b).)*<a\b(?:(?!</?a\b).)*</a>)*(?:(?!" + Regex.Escape(keys[i].ToString()) + @"|</?a\b).)*)(?<tag>" + Regex.Escape(keys[i].ToString()) + @")", @"$1<a href=""http://www.21shipin.com"" target=""_blank"" title=""${tag}"">${tag}</a>");
                if (length != temp.Length)
                {
                    keys.Remove(keys[i]);
                }
                length = temp.Length;
            }
            return temp;
        }
//调用
string str1 = "我想学习c语言教程,我想看的是C语言视频教程,其它什么C语言教程,我都不想看。我喜欢C语言";
string result = keyAddUrl(str1, keys);
richTextBox2.Text = result;
/*------------输出------------
我想学习<a href="http://www.21shipin.com" target="_blank" title="c语言教程">c语言教程</a>,我想看的是<a href="http://www.21shipin.com" target="_blank" title="C语言视频教程">C语言视频教程</a>,其它什么<a href="http://www.21shipin.com" target="_blank" title="C语言">C语言</a>教程,我都不想看。我喜欢C语言
*/


说明:
1、这里的关键字还是要求顺序的,要求被包含的放在前面
2、由于VS2003的限制,只能使用全局变量,如果是局部变量,因每次调用都需要重新声明,降低效率
3、由于不能使用泛型,只能使用ArrayList,需要做类型转换,同样会降低效率
4、由于楼主需求的复杂性,正则表达式必须动态生成,同样会带来效率损失

试下看能不能用吧,如果不能用,哪里报错,报什么错给一下 --------------------编程问答-------------------- Mark --------------------编程问答-------------------- 感谢过客,有一个小问题。。

如果我的字符串本身被链接包含着,应该是跳过的,但是仍然会加链接。如我的字符串是:

string str1 =  ”我想学习c语言教程,我想看的是C语言视频教程,其它什么<a href=\"http://www.21shipin.com\" target=\"_blank\" title=\"C语言\">C语言教程</a>,我都不想看。我喜欢C语言“

结果应该:

string str1 = “我想学习<a href="http://www.21shipin.com" target="_blank" title="c语言教程">c语言教程</a>,我想看的是<a href="http://www.21shipin.com" target="_blank" title="C语言视频教程">C语言视频教程</a>,其它什么C语言教程,我都不想看。我喜欢<a href="http://www.21shipin.com" target="_blank" title="C语言">C语言”</a>“


--------------------编程问答-------------------- --------------------编程问答-------------------- 试下看看这样满不满足你的需求

//Regex reg = new Regex(@"(?i)(?:^|(?<!<a\b(?>[^<>]*))>)(?>[^<>]*)(?:<|$)");
//改为
Regex reg = new Regex(@"(?i)(?:^|(?<!<a\b[^<>]*)>)(?>[^<>]*)(?=<|$)");
--------------------编程问答-------------------- 感觉正则应该更快点 --------------------编程问答-------------------- Arrylist HashTable  正则也可以 up --------------------编程问答--------------------
引用 11 楼 lxcnn 的回复:
试下看看这样满不满足你的需求

C# code//Regex reg = new Regex(@"(?i)(?:^|(?<!<a\b(?>[^<>]*))>)(?>[^<>]*)(?:<|$)");//改为Regex reg=new Regex(@"(?i)(?:^|(?<!<a\b[^<>]*)>)(?>[^<>]*)(?=<|$)");



OK.可以。。

不过我给每个关键字加个动态链接地址时,加上不去。郁闷啊。。还是对正则不懂。。呵呵

如下面的,我增加了一个链接地址数组,使得不同的关键字链接对应的页面,,如何加进去呢?

private string keyAddUrl(string src, ArrayList keys)
{
Regex reg = new Regex(@"(?i)(?:^|(?<!<a\b[^<>]*)>)(?>[^<>]*)(?=<|$)");
return reg.Replace(src, new MatchEvaluator(replaceKey));
}

int length = 0;
string temp1 = string.Empty;        
ArrayList keys = new ArrayList(new string[] { "c语言", "C语言教程", "c语言视频教程" });
ArrayList keys1 = new ArrayList(new string[] { "a.html", "b.html", "c.html" });

private string replaceKey(Match m)
{
temp1 = m.Value;
length = temp1.Length;
for (int i = keys.Count - 1; i >= 0; i--)
{
temp1 = Regex.Replace(temp1, @"(?is)^((?:(?:(?!" + Regex.Escape(keys[i].ToString()) + @"|</?a\b).)*<a\b(?:(?!</?a\b).)*</a>)*(?:(?!" + Regex.Escape(keys[i].ToString()) + @"|</?a\b).)*)(?<tag>" + Regex.Escape(keys[i].ToString()) + @")", @"$1<a href=""http://www.21shipin.com"" target=""_blank"" title=""${tag}"">${tag}</a>");
if (length != temp1.Length)
{
keys.Remove(keys[i]);
}
length = temp1.Length;
}
return temp1;
}

--------------------编程问答-------------------- 是不是这种效果?

        //替换方法 
        private string keyAddUrl(string src, ArrayList keys)
        {
            Regex reg = new Regex(@"(?i)(?:^|(?<!<a\b[^<>]*)>)(?>[^<>]*)(?=<|$)");            
            for(int i=0;i<keys.Count;i++)
            {
                hs.Add(keys[i], keys1[i]);
            }
            return reg.Replace(src, new MatchEvaluator(replaceKey));
        }

        int length = 0;
        string temp = string.Empty;        
        ArrayList keys = new ArrayList(new string[] { "c语言", "C语言教程", "c语言视频教程" });
        ArrayList keys1 = new ArrayList(new string[] { "a.html", "b.html", "c.html" });
        Hashtable hs = new Hashtable();
        private string replaceKey(Match m)
        {
            temp = m.Value;
            length = temp.Length;
            for (int i = keys.Count - 1; i >= 0; i--)
            {
                temp = Regex.Replace(temp, @"(?is)^((?:(?:(?!" + Regex.Escape(keys[i].ToString()) + @"|</?a\b).)*<a\b(?:(?!</?a\b).)*</a>)*(?:(?!" + Regex.Escape(keys[i].ToString()) + @"|</?a\b).)*)(?<tag>" + Regex.Escape(keys[i].ToString()) + @")", @"$1<a href=""http://www.21shipin.com/" + hs[keys[i]].ToString() + @""" target=""_blank"" title=""${tag}"">${tag}</a>");
                if (length != temp.Length)
                {
                    keys.Remove(keys[i]);
                }
                length = temp.Length;
            }
            return temp;
        }
//调用
string str1 = "我想学习c语言教程,我想看的是C语言视频教程,其它什么 <a href=\"http://www.21shipin.com\" target=\"_blank\" title=\"C语言\">C语言教程 </a>,我都不想看。我喜欢C语言";
string result = keyAddUrl(str1, keys);
richTextBox2.Text = result;
/*------------输出------------
我想学习<a href="http://www.21shipin.com/b.html" target="_blank" title="c语言教程">c语言教程</a>,我想看的是<a href="http://www.21shipin.com/c.html" target="_blank" title="C语言视频教程">C语言视频教程</a>,其它什么 <a href="http://www.21shipin.com" target="_blank" title="C语言">C语言教程 </a>,我都不想看。我喜欢<a href="http://www.21shipin.com/a.html" target="_blank" title="C语言">C语言</a>
*/
--------------------编程问答-------------------- 顶下。。 --------------------编程问答--------------------
引用 16 楼 duangjian 的回复:
顶下。。


15楼是否满足需求? --------------------编程问答-------------------- 还没有解决?
下面给你解决的思路,其他代码部分就不写了。

protected string TiHuan(string Nr)
    {
        ArrayList HeChen = new ArrayList();
        string[] NeiRong = new string[1];
        string ZuHeNeiRong = "";
        NeiRong = Nr.Split('<');//首先分割出
        for (int ii = 0; ii < NeiRong.Length; ii++)
        {
            if (NeiRong[ii].IndexOf("a ") < 0 && NeiRong[ii].IndexOf("A ") <= 0)//过滤掉包含指定字符串的内容
            { HeChen.Add(NeiRong[ii].ToString()); }//得到不包含超链接的内容
        }
HeChen得到内容有2个如下:
/*我想学习c语言教程,我想看的是C语言视频教程,我喜欢C语言,我想习学 
/a>',其它什么C语言教程,我都不想看。*/
        for (int i1 = 0; i1 < HeChen.Count; i1++)
        { ZuHeNeiRong += HeChen[i1].ToString(); }
        NeiRong = ZuHeNeiRong.Split('>');//首先分割出,如果需要就再次分割后,再进行组合后输出给字符串关键字加超链接处理,其实这一步已经不需要了,因为包含字符串/a>'已不给替换造成影响了。
            return ZuHeNeiRong;
    }
--------------------编程问答--------------------
string nr = "我想学习c语言教程,我想看的是C语言视频教程,我喜欢C语言,我想习学 <a href='http://www.21shipin.com' target='_blank' title='C语言教程'>c语言教程 </a>',其它什么C语言教程,我都不想看。";
        TiHuan(nr);
--------------------编程问答-------------------- UP --------------------编程问答-------------------- 根据我的网站,把程序修改如下:


ArrayList keys = new ArrayList();
ArrayList keys1 = new ArrayList();
Hashtable hs = new Hashtable();
public  string    addTag(string contents)
{
Open();



SqlDataAdapter adapter = new SqlDataAdapter( "select  * from tag",myConnection );


DataTable dt = new DataTable();
adapter.Fill(dt);


for(int i = 0 ;i<dt.Rows.Count;i++)
{
keys.Add(dt.Rows[i]["tagTitle"].ToString().Trim());
keys1.Add(dt.Rows[i]["tagUrl"].ToString().Trim());
}

contents = keyAddUrl(contents, keys);
keys.Clear();
keys1.Clear();
hs.Clear();

return contents;
}


private string keyAddUrl(string src, ArrayList keys)
{
Regex reg = new Regex(@"(?i)(?:^|(?<!<a\b[^<>]*)>)(?>[^<>]*)(?=<|$)");            
for(int i=0;i<keys.Count;i++)
{
hs.Add(keys[i], keys1[i]);
}
return reg.Replace(src, new MatchEvaluator(replaceKey));
}

int length = 0;
string temp1 = string.Empty;        


private string replaceKey(Match m)
{
temp1 = m.Value;
length = temp1.Length;
for (int i = keys.Count - 1; i >= 0; i--)
{
temp1 = Regex.Replace(temp1, @"(?is)^((?:(?:(?!" + Regex.Escape(keys[i].ToString()) + @"|</?a\b).)*<a\b(?:(?!</?a\b).)*</a>)*(?:(?!" + Regex.Escape(keys[i].ToString()) + @"|</?a\b).)*)(?<tag>" + Regex.Escape(keys[i].ToString()) + @")", @"$1<a href=""http://www.21shipin.com/" + hs[keys[i]].ToString() + @""" target=""_blank"" title=""${tag}"">${tag}</a>");
if (length != temp1.Length)
{
keys.Remove(keys[i]);
}
length = temp1.Length;
}
return temp1;
}




可是一直报 Service Unavailable  我晕,我哭。。。。 --------------------编程问答-------------------- =高人啊。。 --------------------编程问答-------------------- 啥也不说了  收藏了 --------------------编程问答-------------------- 还没解决?
用2个傍晚调试终于实现了。
输出内容如下:
我想学习<a href='a2.html' target='_blank' title='C语言教程'>C语言教程</a>,我想看的是<a href='a1.html' target='_blank' title='C语言视频教程'>C语言视频教程</a>,我喜欢C语言,我想习学<a href='http://www.21shipin.com' target='_blank' title='C语言教程'>C语言教程 </a>,其它什么<a href='a2.html' target='_blank' title='C语言教程'>C语言教程</a>,我都不想看。
哈哈。。。。。。。。。。。。。对这个问题太感兴趣了。
调试也很辛苦啊,如果还没有解决问题,需要的话找我,如果已经解决则付之一笑,当练手了。
--------------------编程问答-------------------- 我想学习<a href='a2.html' target='_blank' title='C语言教程'>C语言教程</a>,我想看的是<a href='a1.html' target='_blank' title='C语言视频教程'>C语言视频教程</a>,我喜欢<a href='a3.html' target='_blank' title='C语言'>C语言</a>,我想习学<a href='http://www.21shipin.com' target='_blank' title='C语言教程'>C语言教程 </a>,其它什么<a href='a2.html' target='_blank' title='C语言教程'>C语言教程</a>,我都不想看。 --------------------编程问答--------------------

mark一下!! --------------------编程问答-------------------- http://blog.csdn.net/xianfajushi/archive/2009/11/11/4787050.aspx --------------------编程问答--------------------
引用 27 楼 xianfajushi 的回复:
http://blog.csdn.net/xianfajushi/archive/2009/11/11/4787050.aspx




1.只替换第一次匹配的关键

有个这点小问题。 --------------------编程问答-------------------- 测试过了每个关键字都替换了
你是怎么测试的我怀疑哦? --------------------编程问答-------------------- 你新建一个页面把代码原封不动复制后测试看
--------------------编程问答-------------------- 请注意公共变量放置的位置问题
public partial class Default2 : System.Web.UI.Page
{
    string nr = "";

    protected void Page_Load(object sender, EventArgs e)
    {

--------------------编程问答-------------------- 学习 --------------------编程问答-------------------- 想问下15楼。你最后的链接地址还是没换 这么办
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,