regexp:反转字符串中的类似元素

时间:2011-10-06 21:38:41

标签: regex

我正在使用我的texteditor(e-texteditor)的正则表达式来尝试反转一行代码中的一些元素。所以这就是我所拥有的:

  [[Date.today, "Today (#{Date.today})"], [Date.tomorrow, "Tomorrow (#{Date.tomorrow})"], [Date.today+3, "In 3 Days (#{Date.today+3})"], [this_weekend, "This Weekend (#{this_weekend})"]]

我实际上想要它的反面:

  [[this_weekend, "This Weekend (#{this_weekend})"], [Date.today+3, "In 3 Days (#{Date.today+3})"], [Date.tomorrow, "Tomorrow (#{Date.tomorrow})"], [Date.today, "Today (#{Date.today})"]]

顺便说一下,如果你想知道代码是在Ruby中。更好地可视化:

有:[A,B,C,D] 想要:[D,C,B,A]

到目前为止,我正在通过搜索

来做蠢事(或者至少我是这么认为的)
 (\[[^[].+?\]),\s(\[[^[].+?\]),\s(\[[^[].+?\]),\s(\[[^[].+?\]) 

所以就像搜索(A),\ s(B),\ s(C),\ s(D)

然后用

替换它
  $4, $3, $2, $1

虽然这样可行,但它不是很好不是它,如果我有超过4个元素怎么办?这还有很多打字。你将如何处理它?<​​/ p>

这是e-texteditor支持的正则表达式'引擎/语法' enter image description here

谢谢!

2 个答案:

答案 0 :(得分:1)

我发布一个awk oneliner来解决你的问题。如果你必须坚持自己的编辑,那就忘了吧。

awk -F'\\[\\[|\\]\\]|\\], *\\[' '{for (i=NF;i>=1;i--) {s=s&&$i?s",":s;s=($i)?s"["$i"]":s"";} s="["s"]";print s}'    yourFile

<强>测试

this is the string we want to test:

kent$  echo {1..10}|sed -r 's/([0-9]+)/[\1],/g;s/^/[/;s/,$/]/'  

[[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]]

现在把它推到我的awk脚本:

kent$  echo {1..10}|sed -r 's/([0-9]+)/[\1],/g;s/^/[/;s/,$/]/'|awk -F'\\[\\[|\\]\\]|\\], *\\[' '{for (i=NF;i>=1;i--) {s=s&&$i?s",":s;s=($i)?s"["$i"]":s"";} s="["s"]";print s}'   

[[10],[9],[8],[7],[6],[5],[4],[3],[2],[1]]

以你给出的例子:

kent$  echo '[[Date.today, "Today (#{Date.today})"], [Date.tomorrow, "Tomorrow (#{Date.tomorrow})"], [Date.today+3, "In 3 Days (#{Date.today+3})"], [this_weekend, "This Weekend (#{this_weekend})"]]'|awk -F'\\[\\[|\\]\\]|\\], *\\[' '{for (i=NF;i>=1;i--) {s=s&&$i?s",":s;s=($i)?s"["$i"]":s"";} s="["s"]";print s}'    

[[this_weekend, "This Weekend (#{this_weekend})"],[Date.today+3, "In 3 Days (#{Date.today+3})"],[Date.tomorrow, "Tomorrow (#{Date.tomorrow})"],[Date.today, "Today (#{Date.today})"]]

答案 1 :(得分:0)

(\[[^[].+?\]),可能是一个有问题的子表达式 它适用于这种情况,因为您提供的样本数据是
形成良好。在形成不良的背景下,它可能会溢出到下一个], 如果没有[之前,即使.+?不贪心。

这可能会更好(\[[^\[\]]+\])

对于你的问题,我认为只有.NET有可变数量的
捕获缓冲区(它的捕获集合),即便如此我也不确定 如何在变更方面使用其可变性。
示例:\[(?:(\[[^\[\]]+\])(?:,\s*|(?=\])))+\]应该制作 一个变量集合,您可以以编程方式 替换方面反向。我从来没有这样做过 太确定了。

否则,它涉及几个单独的中间步骤
在正则表达式之外。

在Perl中,它就像使用全局搜索和替换,其中 替换方是一个回调函数,它传递每个单独的记录。

s / (\[(?:\[[^\[\]]+\](?:,\s*|(?=\])))+\]) / func($ 1)/ eg;`

然后在回调中,解析传递的记录中的各个元素,然后是 以相反的顺序重建字符串,然后将其传递回原始字母 正则表达式用作该记录的替代品。

Perl代码:

use strict;
use warnings;

my $samp = '[[Date.today, "Today (#{Date.today})"], [Date.tomorrow, "Tomorrow (#{Date.tomorrow})"], [Date.today+3, "In 3 Days (#{Date.today+3})"], [this_weekend, "This Weekend (#{this_weekend})"]]';

$samp =~ s/(\[(?:\[[^\[\]]+\](?:,\s*|(?=\])))+\])/ func($1) /eg;

print "\n$samp\n";


sub func
{
   my $rec = shift;
   my @elements = $rec =~ /(\[[^\[\]]+\])/g;
   return '['. join( ', ', reverse @elements ) . ']';
}

输出:

[[this_weekend, "This Weekend (#{this_weekend})"], [Date.today+3, "In 3 Days (#{Date.today+3})"], [Date.tomorrow, "Tomorrow (#{Date.tomorrow})"], [Date.today, "Today (#{Date.today})"]]