Regex 正则表达式仅在给定匹配后替换给定字符的所有引用

Regex 正则表达式仅在给定匹配后替换给定字符的所有引用,regex,perl,replace,Regex,Perl,Replace,为了简单起见,假设我们有以下格式的输入字符串: *text1*|*text2* 所以,我想让text1单独存在,并删除text2中的所有空格 如果我们没有text1,这可能很容易,像这样简单的搜索和替换就可以了: %s/\s//g 但在这种情况下,我不知道该怎么办 我试过这样的方法: %s/\(.*|\S*\).\(.*\)/\1\2/g 这是可行的,但只删除第一个字符,我的意思是,这应该在同一行上为每个违规空间运行一次 因此,首选的限制是仅通过一次搜索和替换来解决此问题。而且,尽管我使用

为了简单起见,假设我们有以下格式的输入字符串:

*text1*|*text2*
所以,我想让text1单独存在,并删除text2中的所有空格

如果我们没有text1,这可能很容易,像这样简单的搜索和替换就可以了:

%s/\s//g
但在这种情况下,我不知道该怎么办

我试过这样的方法:

%s/\(.*|\S*\).\(.*\)/\1\2/g
这是可行的,但只删除第一个字符,我的意思是,这应该在同一行上为每个违规空间运行一次

因此,首选的限制是仅通过一次搜索和替换来解决此问题。而且,尽管我使用了Vim语法,但是使用您最熟悉的正则表达式风格来回答,我的意思是,可能您需要一些仅由Perl提供的功能

编辑: 我的Vim解决方案:

%s:\(|.*\)\@<=\s::g
%s:\(|.*)\@一种方式,在perl中:

s/(^.*\||(?=\s))\s*/$1/g
当然,如果您只允许一次以上的搜索和替换,那么效率可能会更高。

一种方式,在perl中:

s/(^.*\||(?=\s))\s*/$1/g

当然,如果您只允许一次以上的搜索和替换,那么效率可能会更高。

因此您有一个包含一个管道(
|
)的字符串,并且您只想替换管道前面没有的空格

s/\s+(?![^|]*\|)//g

因此,您有一个字符串,其中有一个管道(
|
),您只想替换管道前面没有的空格

s/\s+(?![^|]*\|)//g

您可以尝试将Perl代码嵌入到正则表达式中(使用
(?{…})
语法),但是这是一个实验性的特性,在您的场景中可能不起作用,甚至不可用

这个

理论上应该可以工作,但我遇到了“内存不足!”故障,可以通过将“\s”替换为空格来修复:

s/(.*?\|)(.*)(?{ $x = $2; $x =~ s: ::g })/$1$x/

您可以尝试将Perl代码嵌入到正则表达式中(使用
(?{…})
语法),但是这是一个实验性的特性,在您的场景中可能不起作用,甚至不可用

这个

理论上应该可以工作,但我遇到了“内存不足!”故障,可以通过将“\s”替换为空格来修复:

s/(.*?\|)(.*)(?{ $x = $2; $x =~ s: ::g })/$1$x/

awk
可以很快为您解决这个问题。您的意思是,首先通过awk解析“列”,然后使用sed或其他方法运行搜索并仅替换该列?这与我的实际解决方案类似,但我只想用正则表达式来实现它。@Carl Norum:我安装了awk,但它只是放在那里,什么也不做。或者你指的是awk项目吗?:)+1@ysth,谢谢=)你刚刚在这里完成了一个地狱般的调试任务。@Doppelganger,
awk
也可以进行搜索和替换。当你可以使用一个工具使你想做的事情更清楚(并且更容易引导)时,为什么还要麻烦使用一个复杂的正则表达式呢?
awk
可以很快为你解决这个问题。你的意思是,首先通过awk解析“列”,然后使用sed或其他工具只在该列中运行搜索和替换?这与我的实际解决方案类似,但我只想用正则表达式来实现它。@Carl Norum:我安装了awk,但它只是放在那里,什么也不做。或者你指的是awk项目吗?:)+1@ysth,谢谢=)你刚刚在这里完成了一个地狱般的调试任务。@Doppelganger,
awk
也可以进行搜索和替换。当你可以使用一个工具使你想做的事情更清楚(并且更容易引导)时,为什么还要麻烦使用一个复杂的正则表达式呢?我目前正在阅读一个类似问题的答案,这个问题是我在问了我的问题后才发现的。被接受的响应使用lookaround,因此您的响应可能类似。我还没有摸索过环顾四周,所以我会尝试理解你的解决方案,看看它是否有效。@Doppelganger:环顾在我的解决方案中实际上是不必要的
s/(^.*\| |)\s*/$1/g
也应该可以。我在想“向前看”会让它更快一些,但不知道这是不是真的。我通过“向后看”找到了我的解决方案,但我仍在努力理解你的解决方案。我没有得到这个原子(^.*\| |),我从线的开始到管道都得到了它,但我不明白第二个管道是用来做什么的。第二个管道的意思是“或者什么都没有”。第一次之后,捕获组匹配每个字符前的空字符串。如果
\s*
与任何空格匹配,它们将被丢弃,因为它们不包括在组中。正则表达式的成功在于跳出框框思考我现在正在读一个类似问题的答案,这个问题是我在问了我的问题后才发现的。被接受的响应使用lookaround,因此您的响应可能类似。我还没有摸索过环顾四周,所以我会尝试理解你的解决方案,看看它是否有效。@Doppelganger:环顾在我的解决方案中实际上是不必要的
s/(^.*\| |)\s*/$1/g
也应该可以。我在想“向前看”会让它更快一些,但不知道这是不是真的。我通过“向后看”找到了我的解决方案,但我仍在努力理解你的解决方案。我没有得到这个原子(^.*\| |),我从线的开始到管道都得到了它,但我不明白第二个管道是用来做什么的。第二个管道的意思是“或者什么都没有”。第一次之后,捕获组匹配每个字符前的空字符串。如果
\s*
与任何空格匹配,它们将被丢弃,因为它们不包括在组中。正则表达式的成功在于跳出框框思考比我的好。或者比我的更好。或者
s/\s+(?!.\\\\\\)//gs
如果要进行多个替换,最好执行
s/(\\\\\\.*)/(my$x=$1)=~s\sg$x/se
;不需要
(?{…})
。如果您正在执行多个替换,那么最好执行
s/(\\\124;*)/(我的$x=$1)=~s\sg$x/se
;不需要
(?{…})