2

我是新来的Perl。我有一个这种格式的字符串:
[ timestamp | integer | string ] Some other string here

示例字符串:

[ 2013/05/28 21:39:02 | 2212 | MALFUNCTION  ] Please check for malfunction

timestamp实际上是一个时间戳,例如2013/05/28 20:38:02
整数是一个数字,字符串可以是单词序列中的特定单词。
我有兴趣提取其中的字符串部分。

Java我会这样做很简单:

String s = sentence.substring(line.lastIndexOf("|") + 1, line.lastIndexOf("]")).trim();  

这只是逐个字符地循环字符串并获取感兴趣的部分。
但我不知道这种“问题”是如何解决的Perl
我该怎么做?仅通过正则表达式?

4

5 回答 5

9

它不必是正则表达式,但在 Perl 中它非常方便:

my $str = "[ timestamp | integer | string ] Some other string here";
my ($timestamp, $integer, $string, $other)
   = ($str =~ /\[(.*?)\|(.*?)\|(.*?)\](.*)/);
于 2013-05-28T18:52:37.587 回答
7

你可以像 Java 一样做:

  • String.substringsubstr
  • String.lastIndexOfrindex
  • String.trimsub trim { my $s = $_[0]; $s =~ s/^\s+//; $s =~ s/\s+\z//; $s }
  • +.

但是该方法分别找到最后一个|],而不是第二个和下一个。如果这些字符中的任何一个出现在字符串的后面,它将失败。我会用

my ($ts, $i, $s, $rest) =
   map trim($_),
      /^\[ ([^|]*) \| ([^|]*) \| ([^\]]*) \] (.*)/sx;
于 2013-05-28T18:54:10.267 回答
3

如果您匹配的字符串不包含其他竖线,您可以使用正则表达式:

$fullstring = '[ timestamp | integer | string ] Some other string here';
($string) = ($fullstring =~ /\| *([^|\]]*?) *]/);
于 2013-05-28T18:52:53.417 回答
2

正则表达式是一种自然的 Perl-ish 做事方式。在这种情况下,我们想要最后一个 '|' 之间的字符串 和第一个']',减去它周围的任何空格。

my $string = ($line =~ m/
    \|  #The | character
    \s* #Arbitrary whitespace
    (   #Capture
        [^\|\]]*? #Some number of characters that are not | or ]
    )
    \s* #More whitespace
    \]  # The ] character
    /x)[0];

该成语(m/(reg)ex/)[0]用于从正则表达式中提取第一个捕获组。否则,将返回一个捕获组数组并将其转换为标量(数组的长度)。

/x正则表达式上的修饰符会导致空格和#comments 被忽略。

正则表达式中的*?标记表示“非贪婪”匹配。否则,尾随空格也会被捕获。

于 2013-05-28T19:02:19.760 回答
1

Line can be parsed by splitting on |[] chars, and then trimming spaces for extracted values

my @arr = map { s/^\s+ | \s+$//xg; $_ }  split / [\Q[]|\E] /x, $line;

after that $arr[0] is timestamp $arr[1] is integer, and so on.

于 2013-05-28T18:49:44.623 回答