【问题标题】:perl: substitute character within all bracketsperl:替换所有括号内的字符
【发布时间】:2016-07-28 21:10:59
【问题描述】:

我有这个 PERL 字符串:

my $string = "['-1XA0.55B',40,100,DU(26,3,20),100.00, DU(26,32,99) ]";

并想替换所有 () 括号内的所有逗号,以获得:

my $string = "['-1XA0.55B',40,100,DU(26.3.20),100.00, DU(26.32.99) ]";

谁能帮帮我?

【问题讨论】:

  • 最安全的方法是使用任何用于读取该字符串的解析器,然后将有问题的特定字段与其他字符串分开编辑。然后使用解析器再次以字符串格式输出数据。那么,你有那个解析器吗?
  • 好主意。是的,我只写了一个小解析器来解决这个问题。谢谢;)

标签: string perl character substitution brackets


【解决方案1】:

假设字符串采用您列出的格式。最简单的答案是

my $string = "['-1XA0.55B',40,100,DU(26,3,20),100.00, DU(26,32,99) ]";
$string =~ s/DU\((\d*),(\d*),(\d*)\)/DU\($1.$2.$3\)/g;
print $string;

输出将是 ['-1XA0.55B',40,100,DU(26.3.20),100.00, DU(26.32.99)]

我正在捕获括号中的数字并使用特殊变量 $1、$2、$3 作为我们替换的一部分。

【讨论】:

  • 帮助他了解你做了什么。没有解释的答案对他没有帮助
  • 基本的正则表达式的东西,不知道有什么要解释的。我正在捕获括号中的数字并使用特殊变量 $1、$2、$3 作为我们替换的一部分
  • 你可以解释一下正则表达式
  • Stackoverflow 不是代码工厂,而是社区。写答案时尽量少用力,当提问的人是新手时更是如此
【解决方案2】:

这是一种方法。它首先找到括号内的所有子字符串,并使用@-@+ 内置数组保存一个数组@substr,其中包含每个子字符串的偏移量和长度

然后扫描数组并使用substrtr/// 将所有逗号转换为这些子字符串中的点

use strict;
use warnings 'all';
use feature 'say';

my $string = "['-1XA0.55B',40,100,DU(26,3,20),100.00, DU(26,32,99) ]";

my @substr;
push @substr, [ $-[1], $+[1]-$-[1] ] while $string =~ / \( ( [^()]* ) \) /gx;

substr($string, @$_) =~ tr/,/./ for @substr;

say $string;

输出

['-1XA0.55B'.40.100.DU(26.3.20).100.00. DU(26.32.99) ]

【讨论】:

    【解决方案3】:

    这可以通过正则表达式替换来完成。但它仅限于简单的情况,并且在引用的字符串中没有嵌套的括号或括号,否则它会中断。

    use strict;
    use warnings;
    
    my $string = "['-1XA0.55B',40,100,DU(26,3,20),100.00, DU(26,32,99) ]";
    $string =~ s/\([^()]*\)/$& =~ tr|,|.|r/ge;
    print $string;
    

    输出:

    ['-1XA0.55B',40,100,DU(26.3.20),100.00, DU(26.32.99) ]
    

    我们所做的只是匹配一个文字括号,然后是可选的非括号,然后是另一个括号。然后我们获取匹配的字符串$& 并对其执行音译,将, 更改为.,然后将其作为替换的替换部分返回。 tr/// 上的 /r 修饰符不会尝试更改 $&(这是只读的,所以我们不能),而只是返回结果字符串而不更改 $&。替换 /ge 上的修饰符表示全局匹配,并且替换部分(音译)应作为代码进行评估。

    这也可以用更详细的代码来完成,虽然更复杂,但更能说明问题

    use strict;
    use warnings;
    
    my $string = "['-1XA0.55B',40,100,DU(26,3,20),100.00, DU(26,32,99) ]";
    while ($string =~ /\([^()]*\)/g) {
        my $pos = pos($string);               # remember where we were
        my $match = $&;                       # copy the matched string
        $match =~ tr/,/./;                    # alter the copy
        $string = $` . $match . $';           # reassemble the string
        pos($string) = $pos + length($match); # reset position
    }
    print $string;
    

    这里有很多代码是为了模拟替换正则表达式的工作原理。请注意,由于我们更改了$string 变量,因此我们必须在最后重置匹配位置,从而重置迭代器。变量$` $& $' 分别指的是赛前、比赛和赛后变量。引用最近的正则表达式匹配的匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 2013-01-04
      • 1970-01-01
      • 2019-10-31
      • 2023-03-13
      • 2013-11-25
      相关资源
      最近更新 更多