格式化从X到Y +的字符串

时间:2014-06-18 23:01:32

标签: regex perl bash awk sed

不确定这样做的最好方法,但是我可以使用bash / awk / sed / perl /...?

中的任何一个来完成此操作

简要说明

我希望能够接受这个

(Intra TAU success Times(SGW not change) + Intra TAU success Times(SGW change) + Period TAU success Times(SGW not change)+ Period TAU success Times(SGW change))/(Intra TAU request Times(SGW not change) + Intra TAU request Times(SGW change)+ Period TAU request Times(SGW not change)+ Period TAU request Times(SGW change)) x 100%

并将其格式化为此

([Intra TAU success Times(SGW not change)]+[Intra TAU success Times(SGW change)]+[Period TAU success Times(SGW not change)]+[Period TAU success Times(SGW change)])/([Intra TAU request Times(SGW not change)]+[Intra TAU request Times(SGW change)]+[Period TAU request Times(SGW not change)]+[Period TAU request Times(SGW change)])*100

详细说明

我希望能够采用这种格式(这将是一行,为了清晰起见,jsut就这样呈现)

(
Intra TAU success Times(SGW not change) + 
Intra TAU success Times(SGW change) + 
Period TAU success Times(SGW not change)+ 
Period TAU success Times(SGW change)
)/(
Intra TAU request Times(SGW not change) + 
Intra TAU request Times(SGW change)+ 
Period TAU request Times(SGW not change)+ 
Period TAU request Times(SGW change)
) 
x 100%

并生成以下格式:

(
[Intra TAU success Times(SGW not change)]+
[Intra TAU success Times(SGW change)]+
[Period TAU success Times(SGW not change)]+
[Period TAU success Times(SGW change)]
)/(
[Intra TAU request Times(SGW not change)]+
[Intra TAU request Times(SGW change)]+
[Period TAU request Times(SGW not change)]+
[Period TAU request Times(SGW change)]
)
*100

我想做什么

1为所有计数器添加方括号[]

取此字符串为Intra TAU success Times(SGW not change)
并生成此[Intra TAU success Times(SGW not change)]

注意并非所有计数器字符串都以)

结尾

2将x替换为*

3删除%

5 个答案:

答案 0 :(得分:0)

假设:

STRING="(Intra TAU success Times(SGW not change) + Intra TAU success Times(SGW change) + Period TAU success Times(SGW not change)+ Period TAU success Times(SGW change))/(Intra TAU request Times(SGW not change) + Intra TAU request Times(SGW change)+ Period TAU request Times(SGW not change)+ Period TAU request Times(SGW change)) x 100%"

这适用于您的示例:

echo $STRING | sed 's/Intra/[&/g; s/Period/[&/g; s/change)/&]/g; s/ x / * /g; s/\([0-9]*\)%/\1/g'

假设:

  • 在" Intra"的开始或"期间"是" ["需要添加
  • 在"更改结束时)"是"]"需要添加
  • " x"在两个空格之间
  • 数字和"%"
  • 之间没有空格

关于 sed

  • &表示"整场比赛"
  • \(...\)捕获一个群组,\1吐出第一个捕获的群组 \2吐出第二个......等等

答案 1 :(得分:0)

使用perl正则表达式将大括号中的字母,空格和平衡括号括起来。

use strict;
use warnings;

my $data = do {local $/; <DATA>};

$data =~ s{\s*\bx\b\s*}{*}g;
$data =~ s{%}{}g;
$data =~ s{\s* ( (?:[a-z\s]+|\([a-z\s]+\))+ )(?<!\s) \s*}{[$1]}ixg;

print $data;

__DATA__
(
Intra TAU success Times(SGW not change) + 
Intra TAU success Times(SGW change) + 
Period TAU success Times(SGW not change)+ 
Period TAU success Times(SGW change)
)/(
Intra TAU request Times(SGW not change) + 
Intra TAU request Times(SGW change)+ 
Period TAU request Times(SGW not change)+ 
Period TAU request Times(SGW change)
) 
x 100%

输出:

([Intra TAU success Times(SGW not change)]+[Intra TAU success Times(SGW change)]+[Period TAU success Times(SGW not change)]+[Period TAU success Times(SGW change)])/([Intra TAU request Times(SGW not change)]+[Intra TAU request Times(SGW change)]+[Period TAU request Times(SGW not change)]+[Period TAU request Times(SGW change)])*100

答案 2 :(得分:0)

你也可以试试这个sed命令,

$ sed 's/ + /]+[/g;s/+ /]+[/g;s/(I/([I/g;s/))\//)])\//g;s/) x 100%/])*100/g' file
([Intra TAU success Times(SGW not change)]+[Intra TAU success Times(SGW change)]+[Period TAU success Times(SGW not change)]+[Period TAU success Times(SGW change)])/([Intra TAU request Times(SGW not change)]+[Intra TAU request Times(SGW change)]+[Period TAU request Times(SGW not change)]+[Period TAU request Times(SGW change)])*100

<强>解释

s/ + /]+[/g;         #   Replace all the ` + ` with `]+[`
s/+ /]+[/g;          #   FRom the above output it again replaces `+ ` with `]+[`
s/(I/([I/g;          # Again from the above result, it replaces `(I` with `([I`
s/))\//)])\//g;      # Again from the output of above, it replaces `))/` with `)])/`
s/) x 100%/])*100/g  # Again from the above output, it replaces `) x 100%` with `])*100`

答案 3 :(得分:0)

我有一种感觉,其他一些解决方案不够灵活,无法处理你还没有告诉我们的一些输入案例(此外,我觉得我喜欢和Marpa一起玩),所以这是一个更重要的解决方案。

#!perl
use strict;
use warnings;

use Marpa::R2;
use Data::Dumper;

my $grammar = Marpa::R2::Scanless::G->new({
  source => \(<<'EOGRAMMAR')
    :default ::= action => ::first
    lexeme default = latm => 1

    Expression ::= Division ('x') Percentage
                                   action => expression
    Division ::= Sum ('/') Sum     action => division
    Sum ::= ('(') Sum (')')                  
        | Variable ('+') Sum       action => sum
        | Variable                           

    Percentage ::= Number ('%')
    Variable ::= VariablePart+     action => variable
    VariablePart ::= Words         action => [value]
                 | '(' Words ')'   action => [values]

    Words ~ [A-Za-z ]+
    Number ~ [\d]+
    Whitespace ~ [\s]+
    :discard ~ Whitespace
EOGRAMMAR
});

my $recognizer = Marpa::R2::Scanless::R->new({
  grammar => $grammar,
  semantics_package => 'action',
});

sub action::expression { "$_[1]*$_[2]" }

sub action::division { "($_[1])/($_[2])" }

sub action::sum { "$_[1]+$_[2]" }

sub action::variable {
  my @parts = @_;
  shift @parts;
  @parts = map @$_, @parts;
  s/^\s+// for @parts;
  s/\s+$// for @parts;
  return '[' . join('', @parts) . ']';
}

my $input = do { local $/; <> };
$recognizer->read(\$input);
my $output = $recognizer->value;
if ($output) {
  print $$output, "\n";
  exit 0;
} else {
  print STDERR "Parse failed";
  exit 1;
}

它使用语法来解析您显示的表达式,而语法操作(而不是构建解析树)只是以您要求的格式重构输出。关于空格以及变量名称中可能出现的内容相对自由#34;在输入中,虽然如果有一种我没有捕获的格式的表达式,可能必须修改语法。

答案 4 :(得分:0)

这可能适合你(GNU sed):

sed -r 's/\s*((Intra|Period)[^)]*\))\s*/[\1]/g;s/\s*x\s*/*/;s/%//' file

将以IntraPeriod开头的字符串环绕到以下),并使用方括号删除任何前/后空格。将x替换为*,删除任何前/后空格。最后删除%