【问题标题】:Substitute character not enclosed by brackets不被括号括起来的替换字符
【发布时间】:2017-03-15 12:26:22
【问题描述】:

我有一个包含大括号的字符串,我想用另一个字符 B 替换任何不包含在一对左括号和右括号中的字符 A。所以

ABCDACD{ACDA}ABCD

应该替换为

BBCDBCD{ACDA}BBCD

如何使用正则表达式(例如在 Perl 中)做到这一点?括号不是嵌套的,但也适用于嵌套情况的解决方案会更好。

编辑:更改措辞

【问题讨论】:

  • 非嵌套:A(?![^{}]*\}) - 检查 A 之后的下一个括号(如果有)是否不是结束括号。现在让我寻找一个好的骗子。
  • “同样适用于嵌套案例的解决方案会更好” 为什么,如果您的数据没有嵌套大括号?非嵌套解决方案很简单,但嵌套大括号需要递归模式。
  • @NicolasMalebranche:请您澄清一下您的声明是否“我想用另一个字符B替换一个字符A,如果它不包含在一对左括号和右括号中。”实际上意味着“如果替换值B在大括号内,那么你不会在任何地方用B替换A”
  • @NicolasMalebranche:ABCDACD{ABCDA}ABCD 输入字符串的预期结果是什么(请注意括号内的B)?应该是BBCDBCD{ABCDA}BBCD(括号外的所有As 被替换)还是ABCDACD{ABCDA}ABCD(原字符串不变)?

标签: regex perl


【解决方案1】:

类似的question 之前已经是answered

Perl 实现在替换评估部分会有所不同,但 main idea 是相同的:

使用交替捕获匹配项匹配不需要的上下文(即{.*?})或所需的子字符串(A)(按特定顺序)。然后根据匹配的部分将不想要的捕获替换为自身,并将所需的捕获替换为您的替换:

my $input = "ABCDACD{ACDA}ABCD";
$input =~ s/({.*?})|(A)/{$2 ? "B" : $1}/ge;

演示:https://ideone.com/bK4c1Y

【讨论】:

  • 您的正则表达式错误,如果 B 在花括号内,则失败 ideone.com/kPFT0G
  • @RizwanM.Tuman,您的链接中的输出是BBCDBCD{ABCDA}BBCD。到底哪里出了问题?
  • Op 写道:“我想用另一个字符 B 替换一个字符 A,如果它不包含在一对左括号和右括号中。”这意味着如果替换值 B 在大括号内,那么您不会在任何地方用 B 替换 A
  • @RizwanM.Tuman:我想你误会了,当A不在花括号内时,OP想用B替换A
  • 所以,我删除了答案......对于误导性问题和缺乏样本 i/o 感觉很傻:|
【解决方案2】:

这是一个分步完成工作的 Perl 解决方案。首先,它将字符串拆分为大括号/非大括号项目。然后对没有支撑的项目进行替换,最后将项目重新组合在一起:

my $str = 'ABCDACD{ACDA}ABCD';
$str = do {
    my $i = 1; 
    join '', map {$i++ % 2 && $_ =~ s/A/B/g; $_ } split /(\{.*?\})/, $str 
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多