Pregunta

Tengo cadenas de este tipo

NAME1              NAME2          DEPTNAME           POSITION
JONH MILLER        ROBERT JIM     CS                 ASST GENERAL MANAGER 

Quiero que la salida sea nombre1 nombre2 y la posición de cómo puedo hacerlo usando split / expresiones regulares / modelo / etc y sin utilizar módulos de CPAN?

¿Fue útil?

Solución

Si los datos de entrada viene como una matriz de cadenas (@strings), esto

for my $s (@strings) {
   my $output = join ' ',
                map /^\s*(.+)\s*$/ ? $1 : (),
                unpack('A19 A15 x19 A*', $s);
   print "$output\n"
}

extraería y recortar la información necesaria.

  

NOMBRE1 | NOMBRE2 | POSICIÓN

y

  

JONH MILLER | ROBERT JIM | HECHO EN GENERAL MANAGER

(La '|' se incluyeron por mí para una mejor expalnation del resultado)

Regards

RBO

Otros consejos

Se va a depender de si los campos de longitud son fijos, o si están separados pestaña. La forma más fácil (usando split) es si son pestaña separada.

my ($name1, $name2, $deptName, $position) = split("\t", $string);

Si son de longitud fija, y suponiendo que todos ellos están, por ejemplo, 10 caracteres de longitud, puede analizarlo como

my ($name1, $name2, $deptName, $position) = unpack("A10 A10 A10 A10", $string);

Suponiendo que el espacio entre los campos no están fijados de modo Separar una cadena a partir de dos o más espacios para que no se rompa el nombre como JONH MILLER en dos partes .

#!/usr/bin/perl
use strict;
use warning;
my $string = "NAME1              NAME2          DEPTNAME           POSITION
             JONH MILLER        ROBERT JIM     CS                 ASST GENERAL MANAGER ";
my @string_parts = split /\s\s+/, $string;
foreach my $test (@string_parts){  
      print"$test\n";
}

A partir de la muestra allí, un solo espacio pertenece a los datos, pero 2 o más espacios contiguos no lo hacen. De esta manera puede dividir en 2 o más espacios. La única cosa que añadir a esto es el uso de List::MoreUtils::mesh

use List::MoreUtils qw<mesh>;
my @names   = map { chomp; $_ } split /\s{2,}/, <$file>;
my @records = map { chomp; { mesh( @names, @{[ split /\s{2,}/ ]} ) } } <$file>;

Considere el uso de autosplit en una sola línea de Perl desde la línea de comandos:

$ perl -F/\s{2,}/ -ane 'print qq/@F[0,1,3]\n/' file

El de una sola línea se divide en dos o más consecutivos espacios e imprimir el primer, segundo y cuarto campos, correspondientes a NAME1, NAME2 y campos de posición.

Por supuesto, esto se romperá si sólo tiene un único espacio que separa las entradas de NAME1 y NAME2, pero se necesita más información sobre el archivo con el fin de determinar cuál podría ser el mejor curso de acción.

Para dividir el espacio en blanco:

@string_parts = split /\s{2,}/, $string;

Esto dividirá $string en una lista de subcadenas. El separador será el \s+ expresiones regulares, lo que significa uno o más espacios en blanco caracteres . Esto incluye espacios, tabulaciones, y (a menos que me equivoque) saltos de línea.

Editar veo que uno de los requisitos es que no se divida en un solo espacio, pero a dividir en dos o más. He modificado la expresión regular en consecuencia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top