Использование perl для разделения строки, которая может содержать пробелы - PullRequest
12 голосов
/ 18 июня 2010

Хорошо, поэтому я использую perl для чтения файла, который содержит некоторые общие данные конфигурации.Эти данные организованы в заголовки в зависимости от их значения.Ниже приведен пример:

[vars]

# This is how we define a variable!
$var = 10;
$str = "Hello thar!";


# This section contains flags which can be used to modify module behavior
# All modules read this file and if they understand any of the flags, use them
[flags] 
  Verbose =       true; # Notice the errant whitespace!

[path]
WinPath = default; # Keyword which loads the standard PATH as defined by the operating system. Append  with additonal values.
LinuxPath = default;

Цель: используя первую строку в качестве примера «$ var = 10;», я хотел бы использовать функцию split в perl для создания массива, содержащего символы »$ var "и" 10 "в качестве элементов.Используя в качестве примера другую строку:

    Verbose    =         true;
    # Should become [Verbose, true] aka no whitespace is present

Это необходимо, потому что я буду выводить эти значения в новый файл (который будет читать другой фрагмент кода C ++) для создания экземпляров объектов словаря.Просто чтобы дать вам небольшой вкус того, как это может выглядеть (просто придумывая, как я иду вперед):

define new dictionary
name: [flags]
# Start defining keys => values
new key name: Verbose
new value val: 10 
# End dictionary

О, и вот код, который у меня есть в настоящее время вместе с тем, что он делает (неправильно):

sub makeref($)
{
    my @line = (split (/=/)); # Produces ["Verbose", "    true"];
}

Чтобы ответить на один вопрос, почему я не использую Config :: Simple, я изначально не знал, как будет выглядеть мой файл конфигурации, только то, что я хотел.Придумывая все это - по крайней мере то, что мне показалось разумным - и используя perl для анализа файла.

Проблема в том, что у меня есть некоторый код C ++, который будет загружать информацию в конфигурационном файле, но поскольку синтаксический анализ в C или C ++ :(, я решил использовать perl. Это также хорошее упражнение для меня, так как яЯ новичок в этом языке. Так вот в чем дело, этот Perl-код на самом деле не является частью моего приложения, он просто облегчает чтение информации для кода C ++. И он более читабелен (как файл конфигурации, так исгенерированный файл). Спасибо за отзыв, он действительно помог.

Ответы [ 5 ]

6 голосов
/ 18 июня 2010

Если вы делаете этот анализ как учебное упражнение, это нормально. Однако CPAN имеет несколько модулей, которые сделают большую работу за вас.

use Config::Simple;
Config::Simple->import_from( 'some_config_file.txt', \my %conf );
3 голосов
/ 18 июня 2010

split разбивает регулярное выражение, поэтому вы можете просто поместить пробел вокруг знака = в его регулярное выражение:

split (/\s*=\s*/, $line);

Вы, очевидно, не хотите удалять все пробелов, иначе будет создана такая строка (пробелы отсутствуют в строке):

$str="Hellothere!";

Я полагаю, что достаточно удалить только пробелы в начале и конце строки:

$line =~ s/^\s*(.*?)\s*$/$1/;

Более простая альтернатива с двумя утверждениями:

$line =~ s/^\s+//;
$line =~ s/\s+$//;
2 голосов
/ 18 июня 2010

Похоже, у вас это есть.Удалите пробелы перед разделением.

sub makeref($)
{
    s/\s+//g;
    my @line = (split(/=/)); # gets ["verbose", "true"]
}
1 голос
/ 18 июня 2010

Этот код добивается цели (и более эффективен без реверса).

for (@line) {
    s/^\s+//;
    s/\s+$//;
}
0 голосов
/ 18 июня 2010

Вы, наверное, все поняли, но я подумал, что добавлю немного.Если вы

sub makeref($)
{
   my @line = (split(/=/));
   foreach (@line)
   {
      s/^\s+//g;
      s/\s+$//g;
   }
}

, то вы удалите пробелы до и после левой и правой стороны.Таким образом, что-то вроде:

 this is a parameter         =      all sorts of stuff here

не будет иметь сумасшедших пробелов.

!! Предупреждение: я, вероятно, не знаю, о чем говорю !!

...