2016-04-14 16 views
0

Aşağıdaki kodda bir değişkende bir model için grep yapmaya çalışıyorum. Değişkenin içinde çok satırlı bir metin var.Perl grep desen için çok satırlı çıkış

$output yılında

satırlı metin bu

_skv_version=1 
COMPONENTSEQUENCE=C1- 

BEGIN_C1 
     COMPONENT=SecurityJNI 
TOOLSEQUENCE=T1- 
END_C1 
CMD_ID=null 
CMD_USES_ASSET_ENV=null_jdk1.7.0_80 
CMD_USES_ASSET_ENV=null_ivy,null_jdk1.7.3_80 
BEGIN_C1_T1 
CMD_ID=msdotnet_VS2013_x64 
CMD_ID=ant_1.7.1 
CMD_FILE=path/to/abcI.vc12.sln 
BEGIN_CMD_OPTIONS_RELEASE 
    -useideenv 

Ben desen

use strict; 
use warnings; 

my $cmd_pattern = "CMD_ID=|CMD_USES_ASSET_ENV="; 
my @matching_lines; 
my $output = `cmd to get output` ; 
print "output is : $output\n"; 

if ($output =~ /^$cmd_pattern(?:null_)?(\w+([\.]?\w+)*)/s) { 
     print "1 is : $1\n"; 
      push (@matching_lines, $1); 
    } 

ben $output beklendiği gibi satırlı çıktı alıyorum ama regex desen maçı için grep kullanıyorum kod benziyor $output üzerinde kullanıyorum bana herhangi bir sonuç vermiyor.

İstenilen düzenli ifadenin İlişkin çıkış

jdk1.7.0_80 
ivy 
jdk1.7.3_80 
msdotnet_VS2013_x64 
ant_1.7.1 

cevap

1

:

  • Bir if (aksi takdirde sadece bir kez eşleşen olacağım) değil bir while gerek; Bu değişikliği yaptıktan zaman da o kimse seni kullanımını (sonundaki nota bakınız)
  • yapmıyoruz . maçı \n, yapar gibi /gc değiştiriciler
  • Gerçekten, /s değiştirici gerekmez gerekir
  • Sen ^
  • Haklısınız ^ sonra normal ifadeye \s* eklemek istediğiniz dize sadece başlangıcı her yeni satırın başıyla eşleşir ve Öyle değil çünkü en az birinde, /m değiştirici kullanmak istiyorum satırlarınızda lider bir alanınız var
  • $cmd_pattern çevresinde kira sözleşmesi; aksi takdirde, iki seçenek, ayrıca (.+) aşağı (\w+([\.]?\w+)*) bit kolaylaştırabilirsiniz ^CMD_ID= olmanın ilk ve ifade

geri kalanı tarafından takip olmanın ikincisi CMD_USES_ASSET_ENV= alıyoruz.

sonuç şöyle olacaktır:

while ($output =~ /^\s*(?:$cmd_pattern)(?:null_)?(.+)/gcm) {    
    print "1 is : $1\n";    
    push (@matching_lines, $1); 
} 

, normal ifadeniz hala ivy ve kendi başına jdk1.7.3_80 bölünmüş olmaz söyleniyor;

while ($output =~ /^\s*(?:$cmd_pattern)(?:null_)?(.+)/gcm) {   
    my $text = $1; 
    my @text; 
    if ($text =~ /,/) { 
    @text = split /,(?:null_)?/, $text; 
    } 
    else { 
    @text = $text; 
    } 

    for (@text) { 
    print "1 is : $_\n"; 
    push (@matching_lines, $_); 
    } 
} 

sen kalacaksın tek sorun yalnız hat CMD_ID=null: Ben bir bölünme eklenmesi ve böyle bir şeyle _null çıkarmadan öneririm. Bunu size bırakacağım :-)

(Kısa bir süre önce düzenli ifadeler için en iyi uygulamalara bir blog yazısı yazdım - http://blog.codacy.com/2016/03/30/best-practices-for-regular-expressions/ - Perl'de her zaman /s'u gerektiren bir not bulacaksınız; Burada ihtiyacınız yok ki, gerçekten ihtiyacınız olanları kullanmıyorsunuz ve bu, /s

'un anlamından emin olmadığınız anlamına gelebilir