怎么删除字符串中相同的内容?

当然是学习啦,做东西我至于这么难为自己么
while(s/(\d{3}\.ccc\.ddd)((\d{3}\.ccc\.ddd)*?)\1/\1\2/g){}
一句的实现:

$html = "123456.ccc.ddd333.ccc.ddd123.ccc.ddd333.ccc.ddd444.ccc.ddd444.ccc.ddd123.ccc.ddd333.ccc.ddd123.ccc.ddd333.ccc.ddd444.ccc.ddd444.ccc.ddd123.ccc.ddd333.ccc.ddd123.ccc.ddd333.ccc.ddd444.ccc.ddd444.ccc.ddd123.ccc.ddd333.ccc.ddd123456.ccc.ddd333.ccc.ddd444.ccc.ddd444.ccc.ddd";

$html =~ s/((?<=^)|(?<=\.ddd))(.+\.ccc\.ddd)(?=.*\2)//g;

print "$html\n";  ### 123.ccc.ddd123456.ccc.ddd333.ccc.ddd444.ccc.ddd


[Copy to clipboard] [ - ]
CODE:
((?<=^)|(?<=\.ddd))(.+\.ccc\.ddd)(?=.*\2)

不是很看的明白
<=是什么意思
(?<=)  这是一个完整语法, 断言位置之前有某些字符串

举例:
$str = "ab";
如果 $str =~ s/ab/c/;  ### "c"
如果 $str =~ s/(?<=a)b/c/;  ### "ac"


[Copy to clipboard] [ - ]
CODE:
((?<=^)|(?<=\.ddd))(.+\.ccc\.ddd)(?=.*\2)

还是看不太明白这段
晚上回家用这楼解释给你:>



先把((?<=^)|(?<=\.ddd))(.+\.ccc\.ddd)(?=.*\2)分成A, B, C三部分, 依次是三对小括号:

A: ((?<=^)|(?<=\.ddd))
A是两个断言逻辑或在一起的:
A1: (?<=^) 断言当前位置前面紧邻行首
A2: (?<=\.ddd) 断言当前位置前面紧邻".ddd"

B: (.+\.ccc\.ddd)
匹配若干字符, 以".ccc.ddd"结尾

C: (?=.*\2)
\2是引用B部分的整个匹配结果
断言从当前位置后面直到行尾, 存在B匹配到的字符串


-------------------------------- Example Begin ---------------------------------------------
举例, $html = "123.ccc.ddd333.ccc.ddd123.ccc.ddd123.ccc.ddd"
把A, B, C组合起来分析时, 先从非断言的B入手比较直观:

Step 1:
B匹配到123.ccc.ddd, B的前面是行首, 符合A断言, B的后面存在123.ccc.ddd, 符合C断言, 成功.
将B替换为空, 则$html = "333.ccc.ddd123.ccc.ddd123.ccc.ddd"

Step 2:
B匹配到333.ccc.ddd, B的前面是行首, 符合A断言, B的后面不存在333.ccc.ddd, 不符合C断言, 失败.
$html依然="333.ccc.ddd123.ccc.ddd123.ccc.ddd"

Step 3:
B匹配到123.ccc.ddd, B的前面是".ddd", 符合A断言, B的后面存在123.ccc.ddd, 符合C断言, 成功.
将B替换为空, 则$html = "333.ccc.ddd123.ccc.ddd"
-------------------------------- Example End ---------------------------------------------

FAQ:
为什么需要断言A: ((?<=^)|(?<=\.ddd))
答: 若$html = "333.ccc.ddd123.ccc.ddd", 可防止其中的2个"3.ccc.ddd"匹配上.




还不明白的话, 继续讨论吧 :>

差不多了明白了
辛苦了