Regex 在分隔符和正则表达式之间转换文本
我想将西里尔文字符转换为拉丁文字符,仅在特定分隔符-Regex 在分隔符和正则表达式之间转换文本,regex,bash,macos,sed,Regex,Bash,Macos,Sed,我想将西里尔文字符转换为拉丁文字符,仅在特定分隔符-$$和[]之间转换。我在指定转换的范围时遇到问题 我想到了: sed -i '' '/[\[$][^$\[]*[\[$]/ y/АаІіВСсЕеРТтОоКкХхМ/AaIiBCcEePTtOoKkXxM/' wrong.txt 但这将替换以下示例中的所有文本: 错误的.txt: $ПRöVS$ $NUМ| Y$$DUСА|T S | Y$аааааааааааа “$АDJ$dhfg[Rööt.GаtNаmа]% $NАММ$\N” §Y
$$
和[]
之间转换。我在指定转换的范围时遇到问题
我想到了:
sed -i '' '/[\[$][^$\[]*[\[$]/ y/АаІіВСсЕеРТтОоКкХхМ/AaIiBCcEePTtOoKkXxM/' wrong.txt
但这将替换以下示例中的所有文本:
错误的.txt:
$ПRöVS$
$NUМ| Y$$DUСА|T S | Y$аааааааааааа
“$АDJ$dhfg[Rööt.GаtNаmа]%
$NАММ$\N”
§Y$VАL$§!“
注意:我使用OSX
注2:转换不是问题,正则表达式是
预期输出(即指定标记内的文本变为拉丁语):
$证明$
$NUM | Y$$DUCATS | Y$баааааааааааа
“$ADJ$dhfg[Root.GetName]%
$NAME$\n“
§Y$VAL$§!“
[GetCapitalName]
使用sed进行这项工作(通常)会有点痛苦,Perl或awk解决方案可能会更短,可读性更好,但这里有一个在sed中使用的解决方案
它被称为
sed -E -f sedscr.sed wrong.txt
其中,error.txt
是您的输入,sed脚本位于sedscr.sed
中,如下所示:
/\$[^$]*\$/ {
:label1
h
s/.*(\$[^$]*\$).*/\1/
y/АаІіВСсЕеРТтОоКкХхМ/AaIiBCcEePTtOoKkXxM/
s/\$/~~/g
G
s/(.*)\n(.*)\$[^$]*\$(.*)/\2\1\3/
/\$[^$]*\$/b label1
s/~~/$/g
}
/\[[^]]*\]/ {
:label2
h
s/.*(\[[^]]*\]).*/\1/
y/АаІіВСсЕеРТтОоКкХхМ/AaIiBCcEePTtOoKkXxM/
s/[][]/~~/g
G
s/(.*)\n(.*)\[[^]]*\](.*)/\2\1\3/
/\[[^]]*\]/b label2
:label3
s/~~/[/
s/~~/]/
/~~/b label3
}
两个主块分别检查该行是否包含$$
或[]
对,如果是,则进行翻译。模式总是一样的:假设你的线条看起来像
abcdef $abc$ abcdef $def$ abc
~~DEF~~
abcdef $abc$ abcdef $def$ abc
你想把它音译成大写。首先,我们将模式空间复制到保留空间(h
),然后删除最后一对标记(s/*(\$[^$]*\$)./\1/
)之外的所有内容。现在我们用y/abcdef/abcdef/
音译
为了标记a对完成,我们将其替换为文本中没有的内容:两个~
字符(s/\$/~/g
)G
将保留空间附加到模式空间,现在看起来像
abcdef $abc$ abcdef $def$ abc
~~DEF~~
abcdef $abc$ abcdef $def$ abc
复杂的替换s/(.*)\n(.*)\$[^$]*\$(.*)/\2\1\3/
会导致
abcdef $abc$ abcdef ~~DEF~~ abc
现在,我们检查是否还有一对$
,如果是,我们将分支到:label1
(/\$[^$]*\$/b label1
)。当我们不再进行分支时,所有的$
都已处理完毕,我们可以再次将~~
替换为$
(s/~/$/g
)
第二块中的[]
原则上相同;唯一的区别是在替换~
时,我们使用另一个循环,因为我们必须交替插入[
和]
这是输出:
$sed-E-f sedscr.sed-error.txt
挈挈挈挈挈挈挈挈挈挈挈挈挈$证明$
$NUM | Y$$DUCATS | Y$баааааааааааа
“$ADJ$dhfg[Root.GetName]%
$NAME$\n“
§Y$VAL$§!“
或者,更具说明性的是,在我的终端仿真器中显示非拉丁字符的前后:
看起来分隔的是拉丁字符,而不是西里尔字母。还有,这种转变正确吗?我的俄语非常生疏,但是
С
应该变成S
,而П
变成R
,不?需要什么输出?根本问题是y
在匹配的情况下作用于整行。地址只决定这一点,而不选择行的哪一部分。@BenjaminW。如果你想指定西里尔字母,这些字母是乌克兰字母。而且它们在视觉上看起来可能是一样的,你可以检查,它们实际上不是。你能添加预期的输出吗?谢谢,它起作用了。但如何抑制输出的打印?我尝试在-E
之后添加-n
,但它阻止了命令的执行。@AlCrow是否就地替换sed-i'-E-f sedscr.sed-error.txt应该可以工作。