繁体   English   中英

Perl 正则表达式组合捕获组和第 n 个字符串

[英]Perl regex combining capture groups & nth string

我有如下文件:

<div title="alpha" Mauris eu justo sed nisi aliquet blandit. <span name="ll">beta</span> Fusce in pharetra nisi. <span name="ll">gamma</span> Aliquam vehicula imperdiet turpis et rhoncus. <span name="ll">delta</span> Donec faucibus augue quis neque dictum, at rutrum dolor placerat.</div>

我尝试在保留 rest 的顺序的同时获取第 n 个name="ll"属性的内容来代替title= content。

例如,第二个name="ll"会让我:

<div title="gamma" Mauris eu justo sed nisi aliquet blandit. <span name="ll">beta</span> Fusce in pharetra nisi. Aliquam vehicula imperdiet turpis et rhoncus. <span name="ll">delta</span> Donec faucibus augue quis neque dictum, at rutrum dolor placerat.</div>

等等。


我的尝试:

find . -type f -exec perl -pi -w -e 's/(title=)"?[^"\s]*"?(.*)((?:.*?\h+class="ll">){1}.*?)\h+class="ll">"?([^"\s]+)"?(<.*)/$1"$3"$2$4/' \{\} \;

我在哪里犯错?

这个 perl 解决方案应该适合您:

# matching 2nd <span name="ll">
perl -pe 's~(title=)"?[^"\s]*"?((?:.*?\h+<span name="ll">){1}.*?)\h+<span name="ll">([^<]+)</span>~$1"$3"$2~' file

<div title="gamma" Mauris eu justo sed nisi aliquet blandit. <span name="ll">beta</span> Fusce in pharetra nisi. Aliquam vehicula imperdiet turpis et rhoncus. <span name="ll">delta</span> Donec faucibus augue quis neque dictum, at rutrum dolor placerat.</div>

# matching 3rd <span name="ll">
perl -pe 's~(title=)"?[^"\s]*"?((?:.*?\h+<span name="ll">){2}.*?)\h+<span name="ll">([^<]+)</span>~$1"$3"$2~' file

<div title="delta" Mauris eu justo sed nisi aliquet blandit. <span name="ll">beta</span> Fusce in pharetra nisi. <span name="ll">gamma</span> Aliquam vehicula imperdiet turpis et rhoncus. Donec faucibus augue quis neque dictum, at rutrum dolor placerat.</div>

正则表达式解释:

解释:

  • (title=) : 匹配title=并在组 #1 中捕获
  • "?[^"\s]+"? :匹配可选引用的非空格字符串
  • ( : 开始捕获组 #2
    • (?: : 启动非捕获组
      • .*? : 匹配任何文本(惰性匹配)
      • \h+ : 匹配 1+ 个空格
      • <span name="ll"> :匹配文本<span name="ll">
    • ){1} :结束非捕获组并重复此组{1}
    • .*? : 匹配任何文本(惰性匹配)
  • ) : 结束捕获组 #2
  • \h+ : 匹配 1+ 个空格
  • <span name="ll"> :匹配文本<span name="ll">
  • ([^<]+) :匹配任何不是>的字符的 1+ 并在组 #3 中捕获
  • </span> : 匹配</span>
  • $1"$3"$2 : 替换零件

不要在一次替换中做所有事情,而是按步骤进行:

perl -wpe '$n = 2;
           @m = /<span name="ll">([^<]+)/g;
           s/title="[^"]+"/title="$m[$n-1]"/;
           s:<span name="ll">\Q$m[$n-1]\E</span> ::;' 

IE

  1. 提取所有可以移动的字符串;
  2. 用想要的字符串替换标题;
  3. 删除包含所需字符串的跨度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM