求助中文替换问题

Vim、Emacs配置和使用
helex
帖子: 3
注册时间: 2009-09-16 14:10

求助中文替换问题

#1

帖子 helex » 2012-03-27 21:52

在网上找了很久,实在找不到答案了,特求各位解决一下。
要处理内容:
=======================
【3月3日】啊不错的风景,xx,不错的风景
【3月12日】淡淡的淡淡的发发发发发,xx,啊啊啊啊啊啊啊宝贝宝贝
【3月31日】麻烦就看看,谢谢,xx,开阶立极;就;就;

问题:
想将每行中的‘xx’替换成每行开头‘【3月X日】’的内容。
我的思路如下,但不知道怎么实现?
先搜索符合‘【】’内容,然后放到一个变量或寄存器内,再用替换命令。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 求助中文替换问题

#2

帖子 eexpress » 2012-03-27 22:18

正则替换,使用$1而已。$1是上次正则的第一个结果。

代码: 全选

● xsel -o|perl -e 'while(<STDIN>){/【(.*)】/;$c=$1;s/xx/$c/;print;}'【3月3日】啊不错的风景,3月3日,不错的风景
【3月12日】淡淡的淡淡的发发发发发,3月12日,啊啊啊啊啊啊啊宝贝宝贝
【3月31日】麻烦就看看,谢谢,3月31日,开阶立极;就;就;
● 鸣学
cao627
帖子: 992
注册时间: 2007-12-05 10:57
系统: ubuntu14.04
来自: 金山

Re: 求助中文替换问题

#3

帖子 cao627 » 2012-03-28 13:58

楼主的问题可概括为这样一种普遍问题:
如何将匹配到的各行上的文本(这个文本可用一个正则表达式(设为REa)匹配到),替换为相应行上其他位置相应的文本(这个文本可用另一个正则表达式(设为REb)匹配到)。

代码: 全选

perl -pi -e '/(REb)/;$c=$1;s/REa/$c/g' txtfile
2楼能不能解释下为什么要:
'/【(.*)】/;$c=$1;s/xx/$c/g'
而不能直接:
'/【(.*)】/;s/xx/$1/g'
我用'/【(.*)】/;s/xx/$1/g'试了下 它只是将xx给删除了,为什么要$c=$1过度一下呢?
helex
帖子: 3
注册时间: 2009-09-16 14:10

Re: 求助中文替换问题

#4

帖子 helex » 2012-03-28 21:09

两位说的是Vim的命令吗?
我想在vim中实现。另外,一行中可能有多个xx需要替换。
头像
lilydjwg
论坛版主
帖子: 4258
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 求助中文替换问题

#5

帖子 lilydjwg » 2012-03-28 21:35

helex 写了:两位说的是Vim的命令吗?
我想在vim中实现。另外,一行中可能有多个xx需要替换。

代码: 全选

:perldo xxx
或者

代码: 全选

:%!perl -pi -e xxx
其实就是正则而已,学会了都一样的。
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 求助中文替换问题

#6

帖子 aerofox » 2012-03-28 21:39

Vim:

代码: 全选

:%s/【\([^】]*\)】.*\zsxx/\1
但是每行只替换一次,要替换多次,只好重复多次这条命令,如果是放到脚本中,可以在后面加 /e 防止报错。

sed:

代码: 全选

sed ':start;s/\(【\([^】]*\)】.*\)xx/\1\2/;t start'
头像
lilydjwg
论坛版主
帖子: 4258
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 求助中文替换问题

#7

帖子 lilydjwg » 2012-03-28 21:59

aerofox 写了:Vim:

代码: 全选

:%s/【\([^】]*\)】.*\zsxx/\1
但是每行只替换一次,要替换多次,只好重复多次这条命令,如果是放到脚本中,可以在后面加 /e 防止报错。

代码: 全选

:%s/\<xx\>/\=matchstr(getline('.'), '^【\zs[^】]*\ze】')/g
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 求助中文替换问题

#8

帖子 eexpress » 2012-03-28 22:16

cao627 写了:楼主的问题可概括为这样一种普遍问题:
如何将匹配到的各行上的文本(这个文本可用一个正则表达式(设为REa)匹配到),替换为相应行上其他位置相应的文本(这个文本可用另一个正则表达式(设为REb)匹配到)。

代码: 全选

perl -pi -e '/(REb)/;$c=$1;s/REa/$c/g' txtfile
2楼能不能解释下为什么要:
'/【(.*)】/;$c=$1;s/xx/$c/g'
而不能直接:
'/【(.*)】/;s/xx/$1/g'
我用'/【(.*)】/;s/xx/$1/g'试了下 它只是将xx给删除了,为什么要$c=$1过度一下呢?
$1是上一次的结果1。那s///一来,就冲掉了。
● 鸣学
cao627
帖子: 992
注册时间: 2007-12-05 10:57
系统: ubuntu14.04
来自: 金山

Re: 求助中文替换问题

#9

帖子 cao627 » 2012-03-29 9:18

$1是上一次的结果1。那s///一来,就冲掉了。
懂了,谢谢。

代码: 全选

sed ':start;s/\(【\([^】]*\)】.*\)xx/\1\2/;t start'

代码: 全选

sed ':start;sed ':start;s/\(【\([^】]*\)】.*\)xx/\1\2/;t start';t start'
学习!

s/\(【\([^】]*\)】.*\)xx/\1\2/
挺巧妙的!
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 求助中文替换问题

#10

帖子 aerofox » 2012-03-29 13:16

lilydjwg 写了:

代码: 全选

:%s/\<xx\>/\=matchstr(getline('.'), '^【\zs[^】]*\ze】')/g
这个高!学习了。
不知如果一行有 xx 而没有【】会不会有问题,不过如果有问题,吧 % 换成 g/^【[^】]*】/ 也可以解决。
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 求助中文替换问题

#11

帖子 aerofox » 2012-03-29 13:19

cao627 写了:
$1是上一次的结果1。那s///一来,就冲掉了。
懂了,谢谢。

代码: 全选

sed ':start;s/\(【\([^】]*\)】.*\)xx/\1\2/;t start'

代码: 全选

sed ':start;sed ':start;s/\(【\([^】]*\)】.*\)xx/\1\2/;t start';t start'
学习!

s/\(【\([^】]*\)】.*\)xx/\1\2/
挺巧妙的!
下面那一行 sed 代码我倒看不懂了,是拷贝+粘贴的故障码?
头像
lilydjwg
论坛版主
帖子: 4258
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 求助中文替换问题

#12

帖子 lilydjwg » 2012-03-29 13:26

aerofox 写了:
lilydjwg 写了:

代码: 全选

:%s/\<xx\>/\=matchstr(getline('.'), '^【\zs[^】]*\ze】')/g
这个高!学习了。
不知如果一行有 xx 而没有【】会不会有问题,不过如果有问题,吧 % 换成 g/^【[^】]*】/ 也可以解决。
如果没有六角括号的话 xx 会直接消失吧。用 g 的办法不错。
cao627
帖子: 992
注册时间: 2007-12-05 10:57
系统: ubuntu14.04
来自: 金山

Re: 求助中文替换问题

#13

帖子 cao627 » 2012-03-29 13:44

下面那一行 sed 代码我倒看不懂了,是拷贝+粘贴的故障码?
是:s/\(【\([^】]*\)】.*\)xx/\1\2/ 吗?

还有这种用法的机理不是很懂,我想请教下你

如文本如下:

yyaaaxxbbb

在其上执行 s's/\(yy.*\)xx/\1/'
得到的结果为:
yyaaabbb

我的理解(以下有色字为匹配和替换的内容):
\(yy.*\)xx匹配到的是:yyaaaxxbbb
yy.*匹配到的是:yyaaaxxbbb

\1 = yy.*
所以结果好像应该是yyaaaxxbbbbbb
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 求助中文替换问题

#14

帖子 aerofox » 2012-03-29 16:13

cao627 写了:
下面那一行 sed 代码我倒看不懂了,是拷贝+粘贴的故障码?
是:s/\(【\([^】]*\)】.*\)xx/\1\2/ 吗?

还有这种用法的机理不是很懂,我想请教下你

如文本如下:

yyaaaxxbbb

在其上执行 s's/\(yy.*\)xx/\1/'
得到的结果为:
yyaaabbb

我的理解(以下有色字为匹配和替换的内容):
\(yy.*\)xx匹配到的是:yyaaaxxbbb
yy.*匹配到的是:yyaaaxxbbb

\1 = yy.*
所以结果好像应该是yyaaaxxbbbbbb
\(yy.*\)xx 是一个整体,yy.* 是其中的一部分,你不能部分大于整体。
我说的不懂的sed代码当然不是我自己贴的,是指你贴的:

代码: 全选

sed ':start;sed ':start;s/\(【\([^】]*\)】.*\)xx/\1\2/;t start';t start'
cao627
帖子: 992
注册时间: 2007-12-05 10:57
系统: ubuntu14.04
来自: 金山

Re: 求助中文替换问题

#15

帖子 cao627 » 2012-03-29 16:53

代码: 全选

sed ':start;sed ':start;s/\(【\([^】]*\)】.*\)xx/\1\2/;t start';t start'
是我贴错了,没注意
\(yy.*\)xx 是一个整体,yy.* 是其中的一部分,你不能部分大于整体
看来:
\( \)xx中的\( \)是在\( \)xx匹配得到内容的基础上排除掉括号外xx(当然这里xx代表字符本身,但也可替换为表达式)匹配得到的内容,然后在这之上做\( \)内表达式的匹配。

做如上理解就顺了。

做下概括:
在txtfile中 ,如何将匹配到的各行上的文本(这个文本可用一个正则表达式(设为REa)匹配到),替换为相应行上其他位置相应的文本(这个文本可用另一个正则表达式(设为REb)匹配到)

方法 1
用sed命令

代码: 全选

sed 's/\(otherRE\( REb \) otherRE \)REa/\1\2/' txtfile
其中\(otherRE\( REb \) otherRE \)要确保能匹配到行首到REa匹配到字符之前的全部内容
回复