[英]Regex to replace all ocurrences of a given character, ONLY after a given match
[英]Replace character in regex match only
我试图在文本文件中搜索正则表达式,然后在匹配范围中仅将一个字符替换为另一个字符。 我的问题是,我无法通过一些简单的方法来做到这一点。
示例源文件:
...
<br>
<a id="some shopitem" ref="#some shop item name 01 a" style="text-decoration:none;"><h3 style="background-color: #ccc;">blah blab hasdk sldk sasdas dasda sd</h3></a>
<table>
<td width="500">
....
那里我需要匹配regexp ref=\\"#[[:alnum:] ]*\\"
(ref =“#任何带有空格的名称”),并用“-”替换匹配的空格,但是当然不要更改另一个空格或正则表达式匹配。
因此结果应如下所示:
....
<br>
<a id="some shopitem" href="#some-shop-item-name-01-a" style="text-decoration:none;"><h3 style="background-color: #ccc;">blah blab hasdk sldk sasdas dasda sd</h3></a>
<table>
<td width="500">
....
仅在bash中的单行命令中甚至不需要某种脚本就可以做到吗? 有什么方法可以替换组中的空格吗? 像sed -rs/ref=\\"#([[:alnum:] ]*\\)/(\\1s/ /-/g)/g'
?
Perl解决方案:
perl -pe 's/(ref="#)([\w\s]+)(")/ ($x,$y,$z)=($1,$2,$3); $y =~ s{\s}{-}g; $x.$y.$z /eg'
关于引用名称中可能出现的内容(下划线,制表符和其他一些空白字符)稍许宽容
仅在bash中的单行命令中甚至不需要某种脚本就可以做到吗?
您的问题以某种方式激发了我的雄心壮志,以实现这一目标……!
varfile=SOURCEFILE && varsubstfile=RESULTFILE && IFS=' ' read -a repl <<< $(sed -r 's/(.*)(ref="#.*?")( .*)/\2/;tx;d;:x' $varfile | sed -e 's/\ /\-/g' | sed ':a;N;$!ba;s/\s/ /g') && for i in "${!repl[@]}"; do needle["$i"]=$(sed 's/\-/\ /g' <<< "${repl["$i"]}"); done && cp $varfile $varsubstfile && for i in "${!needle[@]}"; do sed -ir "s/${needle[i]}/${repl[i]}/g" $varsubstfile; done && unset needle && unset repl && less $varsubstfile && unset varfile && unset varsubstfile
SOURCEFILE
是您的源文件, RESULTFILE
是将输出写入输出的文件的名称,因此请根据需要更改它们。
好吧...这是一个脚本,但它是(该死的)单线:)
我以为整个文件中都会出现ref="#.*"
的情况,否则它会更短(尽管我不记得更短的版本了)。
...而且我真的希望这可以在您的* nix-system上运行:D
varfile=SOURCEFILE && #set variable for the sourcefile varsubstfile=RESULTFILE && #set variable for the resultfile IFS=' ' read -a repl <<< #we're going to read multiple values into an array "repl" #delimited by a space $( #grab only the second capture group (ref="#.*?") sed -r 's/(.*)(ref="#.*?")( .*)/\\2/;tx;d;:x' $varfile | sed -e 's/\\ /\\-/g' | #replace every space in (ref="#.*?") with a dash sed ':a;N;$!ba;s/\\s/ /g' #replace newlines with a space #when there is more than one occurence sed will delimit them with a newline #but i set a space as the delimiter for the read operation, #thus the last replacement ) && #we now have every needed replacement-string in an array called "repl" for i in "${!repl[@]}"; do #iterate over every value in the array we just read needle["$i"]=$(sed 's/\\-/\\ /g' <<< "${repl["$i"]}"); #replace dashes with spaces and store in a new variable done && #and now every original string, the needle we are going to search for #is stored in another array cp $varfile $varsubstfile && #copy sourcefile to resultfile for i in "${!needle[@]}"; do #for every string we are going to replace sed -ir "s/${needle[i]}/${repl[i]}/g" $varsubstfile; #... we replace it! done #technically we're done here #but i like to clean up afterwards and show the result with less unset repl && less $varsubstfile && unset varfile && unset varsubstfile
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.