gpt4 book ai didi

正则表达式查找(/替换)字符串中字符的多个实例

转载 作者:行者123 更新时间:2023-12-01 11:15:12 27 4
gpt4 key购买 nike

我有一个(可能是非常基本的)问题,关于如何构造一个 (perl) 正则表达式,perl -pe 's///g;',它将查找/替换一个指定字符串中的给定字符/字符集。最初,我认为 g "global"标志可以做到这一点,但我显然误解了这里非常核心的东西。 :/

例如,我想消除特定字符串中的任何非字母数字字符(在较大的文本语料库中)。仅举个例子,字符串以 [ 后跟 @ 开头来标识,中间可能有一些字符。

[abc@def"ghi"jkl'123]

下面的正则表达式

s/(\[[^\[\]]*?@[^\[\]]*?)[^a-zA-Z0-9]+?([^\[\]]*?)/$1$2/g;

会找到第一个 ",如果我运行它三次,我就会找到所有三个。同样,如果我想用其他东西替换非字母数字字符怎么办,比如 X。

s/(\[[^\[\]]*?@[^\[\]]*?)[^a-zA-Z0-9]+?([^\[\]]*?)/$1X$2/g; 

为一个实例做了诀窍。但是我怎样才能一次找到所有这些呢?

最佳答案

您的代码不起作用的原因是 /g替换后不重新扫描字符串。它找到给定正则表达式的所有非重叠匹配项,然后替换替换部分。

[abc@def"ghi"jkl'123] , 只有一个匹配项(这是字符串的 [abc@def" 部分,带有 $1 = '[abc@def'$2 = '' ),所以只有第一个 "已删除。

在第一个匹配之后,Perl 扫描剩余的字符串 (ghi"jkl'123]) 寻找另一个匹配,但没有找到另一个 [。 (或 @ )。


我认为最直接的解决方案是使用嵌套搜索/替换操作。外部匹配标识要替换的字符串,内部匹配进行实际替换。

在代码中:

s{ \[ [^\[\]\@]* \@ \K ([^\[\]]*) (?= \] ) }{ $1 =~ tr/a-zA-Z0-9//cdr }xe;

或者用 X 替换每个匹配项:

s{ \[ [^\[\]\@]* \@ \K ([^\[\]]*) (?= \] ) }{ $1 =~ tr/a-zA-Z0-9/X/cr }xe;

我们匹配前缀 [ , 后跟 0 个或多个不是 [ 的字符或 ]@ , 其次是 @ .

\K用于标记匹配的虚拟开始(即到目前为止匹配的所有内容不包括在匹配的字符串中,这简化了替换)。

我们匹配并捕获 0 个或多个不是 [ 的字符或 ] .

最后我们匹配了一个后缀]向前看(因此它也不是匹配字符串的一部分)。

替换部分作为一段代码执行,而不是字符串(如 /e 标志所示)。在这里我们可以使用 $1 =~ s/[^a-zA-Z0-9]//gr$1 =~ s/[^a-zA-Z0-9]/X/gr , 分别,但由于每个内部匹配只是一个字符,因此也可以使用音译。

我们返回修改后的字符串(如 /r 标志所示)并将其用作外部 s 中的替换字符串操作。

关于正则表达式查找(/替换)字符串中字符的多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52845684/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com