如何增加/减少索引标题中的Alpabetic字母

时间:2017-02-14 13:49:05

标签: regex perl

我有一个输入文本,带有分隔符A - Z系列(数字和文本)

的分隔符

Inputfile.csv:

16  ASeries titles
49  ASeries titles
102 ASeries titles
167 BSeries titles
198 BSeries titles
    ...........
178 WSeries titles
187 WSeries titles
187 ZSeries titles

输出文字应为:

<A>
16  ASeries titles
49  ASeries titles
102 ASeries titles
</A>

<B>
167 BSeries titles
198 BSeries titles
</B>
...........
<W>
178 WSeries titles
187 WSeries titles
</W>
<Z>
187 ZSeries titles
</Z>

问题是每当字母序列丢失(X和Y)时输出就会崩溃。

我的代码:

use strict;
use warnings;

my $csvcnt = "";
readString( "Inputfile.csv", \$csvcnt );

my @_alp = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);

#$csvcnt = $alp."_starts\n".$csvcnt;
for ( 0 .. 25 ) {
   if ( $csvcnt !~ m/\n\d+\t$_alp[$_]/i ) {
      pop @_alp, $_alp[$_];
      next;
   }
   if ( $_ > 0 ) {
      $csvcnt =~ s/\n\d+\t$_alp[$_]/\n<\/$_alp[$_-1]>\n<$_alp[$_]>$&/i;
   }
   elsif ( $_alp[$_] == 'Z' ) {
      $csvcnt =~ s/\n\d+\t$_alp[$_]/\n<$_alp[$_]>\n$&\n<\/$_alp[$_-1]>/i;
   }
}


#---------------->
sub readString    #Readfile in Strings

  #---------------->
{
   my $File   = shift;
   my $string = shift;
   open( FILE1, "<$File" )
     or die "\nFailed Reading File [$File]\n\tReason: $!";
   read( FILE1, $$string, -s $File, 0 );
   close(FILE1);
}

如果有人能帮助我,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

我无法弄清楚你的代码在做什么。我可以在那里看到一些真实的肮脏的东西,所以我不会直接复制你的代码,而是在一个合理的输出上做出最好的猜测。例如 - 您似乎正在创建看起来有点像XML的东西,但实际上并非如此。那太讨厌了。

相反,这就是你如何制作一些看起来像你的目标的XML:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my %entry_for; 

#open your input file
open ( my $input, '<', 'Inputfile.csv' ) or die $!;
#iterate line by line
while ( <$input> ) {
   #match the letter for the 'Series'. 
   my ( $letter ) = m/([A-Z])Series/;  
   #insert it into a hash.   
   push ( @{$entry_for{$letter}}, $_ ); 
}

#create a new XML document
my $XML = XML::Twig -> new; 
#set the root element up. 
$XML -> set_root ( XML::Twig::Elt -> new ('root'));

#iterate the letters we found in the file (e.g. skipping over the missing 'X')

foreach my $letter ( sort keys %entry_for ) { 
   #insert a new XML element for this letter. 
   my $element_for_letter = $XML -> root -> insert_new_elt ('last_child', $letter);
   my $text = join "", "\n", @{$entry_for{$letter}};
   $element_for_letter -> set_text($text);
}

$XML -> set_pretty_print('indented');
$XML -> print;

输入数据的输出:

<root>
  <A>
16  ASeries titles
49  ASeries titles
102 ASeries titles
</A>
  <B>
167 BSeries titles
198 BSeries titles
</B>
  <W>
178 WSeries titles
187 WSeries titles
</W>
  <Z>
187 ZSeries titles
</Z>
</root>

但是具有实际XML的附加优势。我可能会建议,您不希望将多个“字段”内联到XML中,而是最好根据需要创建命名子元素或属性。仅仅因为像这样的标记结构的整个点是使它更容易解析。

您的代码特别存在以下问题:

  • 您打开use strict;use warnings,但您的代码实际上并未编译。 “在第12行的void上下文中无用地使用数组元素。”那是因为pop没有做你认为它做的事情。

  • open应该是3个带有词法文件句柄的参数 - 所以`open(我的$ file,'&lt;','Inputfile.csv')或者死掉;

  • read是您使用它的方式,通过传递标量参考,然后尝试将数据插入其中,基于读取文件大小(以字节为单位)。太复杂了,你可以my $csvcnt = do { local $/; <$input> };做同样的事情。

  • 我不完全确定你正在尝试用正则表达式转换做什么,但是对于你真正想要做的事情来说,它实在是太过分了。这是非常难以阅读的。

  • 尝试创建看起来像XML的东西,但实际上并不是XML是一件非常讨厌的事情。如果您要使用定义的数据传输格式,那么您真的应该坚持使用规范。 (你需要一个根节点作为初学者)