源码网,源码论坛,源码之家,商业源码,游戏源码下载,discuz插件,棋牌源码下载,精品源码论坛

 找回密码
 立即注册
查看: 467|回复: 16

[正则表达式] 巧解 JavaScript 中的嵌套替换(强大正则)

[复制链接]

7万

主题

861

回帖

32万

积分

论坛元老

Rank: 8Rank: 8

积分
329525
发表于 2012-9-9 10:28:43 | 显示全部楼层 |阅读模式
如何仅使用JavaScript支持的正则语法,将有嵌套的内容替换 网友wys提问:如何仅使用JavaScript支持的正则语法,将

复制代码 代码如下:
<p>
<table> <p> <p> </table>
<table> <p> <p> </table>
<p>

中<table>...</table>之间的<p>都替换为<br/>?
思考
该问题的难点之一在于JavaScript支持的正则特性实在有限。楼主已经想到了非JavaScript的解法,如下:
复制代码 代码如下:
re=/(?<=<table.*?)(<p>)(?=.*?<\/table>)/gi;
alert (sourcestr.replace(re,"<br>"));

嗯,思路大致是这样。较真起来,即使JavaScript支持逆序环视,上面答案并不能够如愿运行。原因是带有量词的逆序环视(即在(?<=)里面使用?, *, +, {}这样的量词)是更高级的的语法,极少有语言能够支持(特例是.Net)。

但是,像楼主这样的正则问题应该是很普便的一个问题,我们经常需要循环地替换一些内容。该如何解答呢?

思路一

阅读JavaScript的文档,我找到了lastIndex这样的东东。根据这个东东,我形成了这样的思路:
•先按外层循环,找到第一组较大的匹配。正则代码是<table[^>]*>[\s\S]*?<\/table>
•定位到这次匹配结束的起始位置,替换掉这一段字串中所有的<p>。
•循环执行。
我觉得上述思路大致清晰,但是细节太多(每次匹配涉及3个位置点,一个长度),解起来并非从容不迫,最终的代码想必也不会赏心悦目;尤为重要的是,整个思路像是原始的 Crack,而不是高手的 Hack 。而且思路与正则关系不大。我决定换一条路。

思路二

关键是循环和嵌套。还好不是盗梦空间的深层递归。能否将匹配的内容保护起来,替换完之后再放回原位呢?

想到这里,就豁然开朗了。

思路:先找到所有的匹配内容,记路在数组inner中;

同时使用该正则,将原字串split为另一个数组wrapper;

一个重要的特点是,wrapper一定比inner多一个元素,它一一将inner项隔开,并处于最外层。wrapper 和 inner 的关系,就像是一个手掌的5根指头与4个指缝的关系。将中间的元素取出,记下位置,等处理完之后,再将所有的元素粘合在一起。就是这样简单。代码如下(为了让问题更有普使性,我稍改了一下源字串):

复制代码 代码如下:
<script type="text/javascript">
var str="<p> <table> <p> ,<p> </table> <p> <table> <p> <p> </table> <p> <table> <p> <p> </table>";

var patt=/<table[^>]*>[\s\S]*?<\/table>/i;
var wrapper_result=str.split(patt);
var inner_result = str.match(/<table[^>]*>[\s\S]*?<\/table>/ig);

var len=inner_result.length;
var final=wrapper_result[0];

for (i=0; i<len; i++)
{
tmp=inner_result[i].replace(/<p>/gi,"<br>");
final+=tmp+wrapper_result[i+1];
}
alert(final);
</script>

贴图:


更新

果然是能人辈出,评论更精彩!请看评论中的这则代码:
复制代码 代码如下: alert(sourcestr.replace(/<table.*?\/table>/ig, function($1){return $1.replace(/<p>/ig,"<br>")}));
PS: 本站刚刚添加了评论中代码的解析,可以贴代码了。格式见评论部分的图例显示。谢谢合作!
回复

使用道具 举报

1

主题

2万

回帖

321

积分

中级会员

Rank: 3Rank: 3

积分
321
发表于 2023-1-17 03:16:01 | 显示全部楼层
加快速度很快就撒谎
回复 支持 反对

使用道具 举报

0

主题

1万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2023-8-12 14:54:13 | 显示全部楼层
挺不错的东西
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

124

积分

注册会员

Rank: 2

积分
124
发表于 2023-9-1 04:13:39 | 显示全部楼层
哟哟哟哟哟以偶
回复 支持 反对

使用道具 举报

13

主题

2万

回帖

85

积分

注册会员

Rank: 2

积分
85
发表于 2023-11-18 08:51:14 | 显示全部楼层
谢谢您的分享!
回复 支持 反对

使用道具 举报

11

主题

1万

回帖

103

积分

注册会员

Rank: 2

积分
103
发表于 2024-3-11 13:39:49 | 显示全部楼层
撒旦撒旦撒擦擦擦擦
回复 支持 反对

使用道具 举报

2

主题

2万

回帖

499

积分

中级会员

Rank: 3Rank: 3

积分
499
发表于 2024-4-20 01:34:45 | 显示全部楼层
抽根烟,下来看看再说
回复 支持 反对

使用道具 举报

0

主题

1万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2024-5-27 10:10:08 | 显示全部楼层
怕怕怕怕怕怕怕怕怕怕怕怕怕怕
回复 支持 反对

使用道具 举报

2

主题

2万

回帖

99

积分

注册会员

Rank: 2

积分
99
发表于 2024-5-28 05:30:56 | 显示全部楼层
激动人心,无法言表!
回复 支持 反对

使用道具 举报

14

主题

1万

回帖

75

积分

注册会员

Rank: 2

积分
75
发表于 2024-6-15 04:07:35 | 显示全部楼层
谢谢小Y分享
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

手机版|小黑屋|网站地图|源码论坛 ( 海外版 )

GMT+8, 2024-11-22 12:11 , Processed in 0.098464 second(s), 26 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表