java利用正则表达式负向预查功能实现页面内链功能

日期:2016-02-04 23:07:35

留言:0

分类:经验心得

标签: Java

内链替换介绍

有时候网页的新闻内容,产品内容等需要增加一些内链来提升SEO效果,实现的方法可能有很多,这里我分享一下我自己的方法,我的开发语言是java,主要是使用字符串替换方法来实现。

简单java字符串替换代码

  // 要替换的源文本
  String str = "这是一段文字介绍,就是随便填写的一段文字而已。";

  // 出现什么关键词时替换
  String linkName = "文字";

  // 链接地址
  String linkUrl = "http://www.zengdongwu.com";

  // 替换
  String replaceStr = str.replaceAll(linkName, "<a href=\""+ linkUrl +"\">"+ linkName +"</a>");

  // 打印结果
  System.out.println(str);
  System.out.println(replaceStr);
  
  // 控制台输出:
  // 这是一段文字介绍,就是随便填写的一段文字而已。
  // 这是一段<a href="http://www.zengdongwu.com">文字</a>介绍,就是随便填写的一段<a href="http://www.zengdongwu.com">文字</a>而已。

然而,这只能替换简单的文本,如果页面内容有相对复杂的html标签的时候,便会出现误替换,这时候就需要利用正则表达式来进行替换了。

利用正则表达式负向预查实现复杂html内链

什么是正则表达式负向预查

什么是正则表达式这里就不多左介绍,对负向预查比较陌生的朋友我这里引入一段正则表达式手册的原文介绍:

(?!pattern)负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始

复杂的html内容下如何替换内链

这里先来分析一下什么情况下html会变得复杂,例如要替换的内链文字本来就处于一个超链接中,<a href="#">文本</a>,这时候如果直接替换,则变成一个嵌套的超链接,或者文字出现在<img />标签的alt描述中,如<img src="xxx" alt="文本" />,或者是超链接的title中,如<a href="#" title="文本">文本</a>,这些文本都是不可以替换的,有时候项目还要求<h1>-<h6>这些标签里的文本都不能被替换,这时候要替换这种非标签中的内容,则需要在替换时引入正则表达式。

进一步利用正则表达式负向预查功能进行分析,假设要替换的内链名称为 '文本' 二字:

1)<a href="#">这是文本介绍</a>,对于这种情况,我们可以进行选取'文本'后面不能带有</a>标签的,并且可能文本距离</a>标签结束中间还出现一段其他合法字符,则利用正则表达式写法为:文本(?![^<>]*</a>),这段正则表达式的意思就是,匹配'文本'这两个字符,但是不匹配'文本'并且后面带有<或>这两个字符以外的字符零个或多个,然后接着带一个</a>标签的'文本'。

2)<img src="xxx" alt="这是文本介绍" />,对于这种情况,我们可以进行选取'文本'后面不能带有>标签的'文本',但是有一种情况也是带有>并且是合法的,例如<p>这是文本</p>,所以我们要允许后面出现带有>前面有<的情况,这是一对合法的闭合标签,利用正则表达式写法为:文本(?![^<]*>)

3)对于其他标签内部不能替换的需求,其实这个跟第1点的a标签类似,拿h1标签作为例子的话,正则表达式的写法就是:文本(?![^<>]*</h1>),如果要同时匹配非h1-h6的标签,则可以这样写:文本(?![^<>]*</h[1-6]>)

4)如果以上3种情况整合到一起,那么就这样写:文本(?!([^<>]*</a>)|([^<]*>)|([^<>]*</h[1-6]>)),如果要替换的字符是英文字符,并且需要忽略大小写,则可以在替换字符前加上(?i),写法变为:(?i)文本(?!([^<>]*</a>)|([^<]*>)|([^<>]*</h[1-6]>))

java正则表达式负向预查实现页面内链代码

  // 要替换的源文本
  String str = "这是要替换的文本哦,"
    + "<img src=\"xx\" alt=\"不要替换文本我\" />,"
    + "嗯,<a hre=\"#\" title=\"文本我也是打酱油的\">也不要替换文本我吧</a>"
    + "<p>文本我虽然在标签里,但是要被替换</p>"
    + "<h1>我这个大哥文本,别替换我了</h1>";

  // 出现什么关键词时替换
  String linkName = "文本";

  // 链接地址
  String linkUrl = "http://www.zengdongwu.com";

  // 替换表达式
  String pattern = "(?i)" + linkName + "(?!([^<>]*</a>)|([^<]*>)|([^<>]*</h[1-6]>))";
  
  // 替换
  String replaceStr = str.replaceAll(pattern, "<a href=\""+ linkUrl +"\">"+ linkName +"</a>");

  // 打印结果
  System.out.println(str);
  System.out.println(replaceStr);
  
  // 控制台输出:
  // 这是要替换的文本哦,<img src="xx" alt="不要替换文本我" />,嗯,<a hre="#" title="文本我也是打酱油的">也不要替换文本我吧</a><p>文本我虽然在标签里,但是要被替换</p><h1>我这个大哥文本,别替换我了</h1>
  // 这是要替换的<a href="http://www.zengdongwu.com">文本</a>哦,<img src="xx" alt="不要替换文本我" />,嗯,<a hre="#" title="文本我也是打酱油的">也不要替换文本我吧</a><p><a href="http://www.zengdongwu.com">文本</a>我虽然在标签里,但是要被替换</p><h1>我这个大哥文本,别替换我了</h1>

 

PS:提及一下,这个replaceAll方法,是替换文本中所有匹配的字符串,如果只想替换一次,则可以用java提供的另一个方法replaceFirst,如果替换2次,就2次replaceFirst呗。本文为作者原创,请尊重作者劳动成果,转载时请注明引用出处。

给我留言
留言表
ZengDongwu
Hi ~ 当前还没有人留言,欢迎您给我留言 ^_^