Perl: запрос на улучшение моего REGEX (совпадать только с положительными / отрицательными целыми числами / десятичными числами и запятыми) - PullRequest
0 голосов
/ 27 апреля 2018

Трудно описать, что я буду делать. Так что я покажу это на примере.

Моя строка:

my $string = q(
min_entry = -0.236, 0, 0.236 , 0.382, 0.500, 0.618, 0.764
max_entry=0.236, 0.382, 0.500, 0.618, 0.764, 1.000
#jakis komentarz
rsi_confirm= 25,27,30, 32
slope3 = 0.236, 0.382, 0.5, 0.764
min_tp=0.0125 , 0.0236, 0.0382, 0.05, 0.0764, 0.1
interval = 14

[thresholds]
low = 40
high = 40
persistence = 9

Мой шаблон совпадений:

my @match = $string =~ /(([\d-\.]+[, ]+)+[\d-\.]+)/sg;
print Dumper \@match;

Мои результаты:

$VAR1 = [
          '-0.236, 0, 0.236 , 0.382, 0.500, 0.618, 0.764',
          '0.618, ',
          '0.236, 0.382, 0.500, 0.618, 0.764, 1.000',
          '0.764, ',
          '25,27,30, 32',
          '30, ',
          '0.236, 0.382, 0.5, 0.764',
          '0.5, ',
          '0.0125 , 0.0236, 0.0382, 0.05, 0.0764, 0.1',
          '0.0764, '
        ];

Я не знаю, почему или как элементы с индексом 1 (значение '0,618,',), 3 (значение '0,764,',), 5, 7, 9 добавляются с моим регулярным выражением. Но мне это не нужно.

Результат, который я хотел бы достичь:

print Dumper \@match;
$VAR1 = [
          '-0.236, 0, 0.236 , 0.382, 0.500, 0.618, 0.764',
          '0.236, 0.382, 0.500, 0.618, 0.764, 1.000',
          '25,27,30, 32',
          '0.236, 0.382, 0.5, 0.764',
          '0.0125 , 0.0236, 0.0382, 0.05, 0.0764, 0.1',
        ]

Ответьте, пожалуйста, основываясь на моем регулярном выражении. Единственные идентифицирующие символы повторяющейся строки - это «=» или «=» (перед шаблоном) и «,» (в середине шаблона)

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

Вместо того, чтобы использовать группы захвата, вы хотите использовать кластеризацию для группировки этих частей вашего регулярного выражения. Кластеризация выполняется с помощью (?:whatever) вместо (whatever), чтобы ваш код стал ...

my @match = $string =~ /(?:(?:[\d-\.]+[, ]+)+[\d-\.]+)/sg;
0 голосов
/ 27 апреля 2018

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

Вот пример того, что я хотел бы сделать, используя дескриптор файла DATA. Buliding @aoa сводится к одному утверждению. Конечно, вы можете открыть файл и использовать его вместо этого

Ошибки в вашем коде привели к игнорированию строк только с одним числом (без запятой). Возможно, вам нужно такое поведение, но я «исправил» его здесь

use strict;
use warnings 'all';

my @aoa = map { /-?\d+(?:\.\d+)?/g } <DATA>;

use Data::Dumper;
print Dumper \@aoa;

__DATA__
min_entry = -0.236, 0, 0.236 , 0.382, 0.500, 0.618, 0.764
max_entry=0.236, 0.382, 0.500, 0.618, 0.764, 1.000
#jakis komentarz
rsi_confirm= 25,27,30, 32
slope3 = 0.236, 0.382, 0.5, 0.764
min_tp=0.0125 , 0.0236, 0.0382, 0.05, 0.0764, 0.1
interval = 14

[thresholds]
low = 40
high = 40
persistence = 9

выход

$VAR1 = [
          [
            '-0.236',
            '0',
            '0.236',
            '0.382',
            '0.500',
            '0.618',
            '0.764'
          ],
          [
            '0.236',
            '0.382',
            '0.500',
            '0.618',
            '0.764',
            '1.000'
          ],
          [],
          [
            '25',
            '27',
            '30',
            '32'
          ],
          [
            '3',
            '0.236',
            '0.382',
            '0.5',
            '0.764'
          ],
          [
            '0.0125',
            '0.0236',
            '0.0382',
            '0.05',
            '0.0764',
            '0.1'
          ],
          [
            '14'
          ],
          [],
          [],
          [
            '40'
          ],
          [
            '40'
          ],
          [
            '9'
          ]
        ];

Я также подозреваю, что даже это не лучшее решение вашей проблемы, поскольку вы отбрасываете все метки данных, поэтому не знаете, какой список чисел относится к какой категории, кроме как по позиции

Эта альтернатива создает хэш массивов, так что значение сохраняется

use strict;
use warnings 'all';

my %data;

while ( <DATA> ) {
     next unless /=/;
     my ($key, @values) = /[-\w.]+/g;
     $data{$key} = \@values;
}

use Data::Dumper;

print Dumper \%data;


__DATA__
min_entry = -0.236, 0, 0.236 , 0.382, 0.500, 0.618, 0.764
max_entry=0.236, 0.382, 0.500, 0.618, 0.764, 1.000
#jakis komentarz
rsi_confirm= 25,27,30, 32
slope3 = 0.236, 0.382, 0.5, 0.764
min_tp=0.0125 , 0.0236, 0.0382, 0.05, 0.0764, 0.1
interval = 14

[thresholds]
low = 40
high = 40
persistence = 9

выход

$VAR1 = {
          'high' => [
                      '40'
                    ],
          'interval' => [
                          '14'
                        ],
          'slope3' => [
                        '0.236',
                        '0.382',
                        '0.5',
                        '0.764'
                      ],
          'persistence' => [
                             '9'
                           ],
          'low' => [
                     '40'
                   ],
          'min_tp' => [
                        '0.0125',
                        '0.0236',
                        '0.0382',
                        '0.05',
                        '0.0764',
                        '0.1'
                      ],
          'min_entry' => [
                           '-0.236',
                           '0',
                           '0.236',
                           '0.382',
                           '0.500',
                           '0.618',
                           '0.764'
                         ],
          'max_entry' => [
                           '0.236',
                           '0.382',
                           '0.500',
                           '0.618',
                           '0.764',
                           '1.000'
                         ],
          'rsi_confirm' => [
                             '25',
                             '27',
                             '30',
                             '32'
                           ]
        };

Это лучшее, что я могу сделать для вас, не понимая всей проблемы

0 голосов
/ 27 апреля 2018

У вас есть две группы скобок, одна внутри другой. Внутренний дает каждый второй результат. Вы должны использовать группу без захвата для внутренней группировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...