Как я могу извлечь подстроки из строки в Perl?

Я думаю, что необходимо все еще быть в состоянии использовать Гудзон. Гудзон очень гибок и позволяет Вам также использовать сценарии оболочки для создания: Сценарии оболочки и Windows Batch Commands

Просто входят там xcodebuild. Смотрите на xcodebuild страницу справочника для наблюдения опций xcodebuild.

15
задан brian d foy 18 September 2009 в 23:01
поделиться

7 ответов

Вы можете сделать что-то вроде этого:

my $data = <<END;
1) Scheme ID: abc-456-hu5t10 (High priority) *
2) Scheme ID: frt-78f-hj542w (Balanced)
3) Scheme ID: 23f-f974-nm54w (super formula run) *
END

foreach (split(/\n/,$data)) {
  $_ =~ /Scheme ID: ([a-z0-9-]+)\s+\(([^)]+)\)\s*(\*)?/ || next;
  my ($id,$word,$star) = ($1,$2,$3);
  print "$id $word $star\n";
}

Ключевым моментом является Регулярное выражение:

Scheme ID: ([a-z0-9-]+)\s+\(([^)]+)\)\s*(\*)?

Которое распадается следующим образом.

Фиксированная строка «ID схемы:»:

Scheme ID: 

За которым следует один или несколько символов az, 0-9 или -. Мы используем скобки, чтобы записать его как $ 1:

([a-z0-9-]+)

, за которым следует один или несколько пробельных символов:

\s+

За ним следует открывающая скобка (которую мы экранируем), за которой следует любое количество символов, не являющихся закрывающей скобкой, а затем закрывающая скобка (экранированная). Мы используем неэкранированные скобки, чтобы записать слова как $ 2:

\(([^)]+)\)

, за которыми следуют некоторые пробелы, может быть, *, записанные как $ 3:

\s*(\*)?
32
ответ дан 1 December 2019 в 00:45
поделиться

Вы можете использовать регулярное выражение, например следующее:

/([-a-z0-9]+)\s*\((.*?)\)\s*(\*)?/

Так, например:

$s = "abc-456-hu5t10 (High priority) *";
$s =~ /([-a-z0-9]+)\s*\((.*?)\)\s*(\*)?/;
print "$1\n$2\n$3\n";

печатает

abc-456-hu5t10
High priority
*
4
ответ дан 1 December 2019 в 00:45
поделиться
(\S*)\s*\((.*?)\)\s*(\*?)


(\S*)    picks up anything which is NOT whitespace
\s*      0 or more whitespace characters
\(       a literal open parenthesis
(.*?)    anything, non-greedy so stops on first occurrence of...
\)       a literal close parenthesis
\s*      0 or more whitespace characters
(\*?)    0 or 1 occurances of literal *
3
ответ дан 1 December 2019 в 00:45
поделиться

Ну, здесь один лайнер:

perl -lne 'm|Scheme ID:\s+(.*?)\s+\((.*?)\)\s?(\*)?|g&&print "$1:$2:$3"' file.txt

Расширен до простого скрипта, чтобы немного лучше объяснить ситуацию:

#!/usr/bin/perl -ln              

#-w : warnings                   
#-l : print newline after every print                               
#-n : apply script body to stdin or files listed at commandline, dont print $_           

use strict; #always do this.     

my $regex = qr{  # precompile regex                                 
  Scheme\ ID:      # to match beginning of line.                      
  \s+              # 1 or more whitespace                             
  (.*?)            # Non greedy match of all characters up to         
  \s+              # 1 or more whitespace                             
  \(               # parenthesis literal                              
    (.*?)            # non-greedy match to the next                     
  \)               # closing literal parenthesis                      
  \s*              # 0 or more whitespace (trailing * is optional)    
  (\*)?            # 0 or 1 literal *s                                
}x;  #x switch allows whitespace in regex to allow documentation.   

#values trapped in $1 $2 $3, so do whatever you need to:            
#Perl lets you use any characters as delimiters, i like pipes because                    
#they reduce the amount of escaping when using file paths           
m|$regex| && print "$1 : $2 : $3";

#alternatively if(m|$regex|) {doOne($1); doTwo($2) ... }     

Хотя, если бы это было что-то другое, кроме форматирования, я бы реализовал основной цикл для обработки файлов и наполнения тела сценария, а не полагаться на переключатели командной строки для цикла.

2
ответ дан 1 December 2019 в 00:45
поделиться

Давно не было Perl

while(<STDIN>) {
    next unless /:\s*(\S+)\s+\(([^\)]+)\)\s*(\*?)/;
    print "|$1|$2|$3|\n";
}
1
ответ дан 1 December 2019 в 00:45
поделиться

Это просто требует небольшого изменения моего последнего ответа :

my ($guid, $scheme, $star) = $line =~ m{
    The [ ] Scheme [ ] GUID: [ ]
    ([a-zA-Z0-9-]+)          #capture the guid
    [ ]
    \(  (.+)  \)             #capture the scheme 
    (?:
        [ ]
        ([*])                #capture the star 
    )?                       #if it exists
}x;
1
ответ дан 1 December 2019 в 00:45
поделиться

Строка 1:

$input =~ /'^\S+'/;
$s1 = $&;

Строка 2:

$input =~ /\(.*\)/;
$s2 = $&;

Строка 3:

$input =~ /\*?$/;
$s3 = $&;
0
ответ дан 1 December 2019 в 00:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: