Как избежать предупреждений в замене регулярных выражений Perl альтернативами? - PullRequest
0 голосов
/ 27 октября 2018

У меня есть это регулярное выражение.

$string =~ s/(?<!["\w])(\w+)(?=:)|(?<=:)([\w\d\\.+=\/]+)/"$1$2"/g;

Само регулярное выражение работает отлично.

Но так как я заменяю альтернативы (и глобально), я всегда получаю предупреждение, что $ 1 или $ 2 неинициализированы. Эти предупреждения загромождают мой лог-файл.

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

Дополнительный вопрос: возможно, есть какой-то лучший способ сделать это, например, вообще не используете регулярные выражения? Я исправляю JSON, где некоторые пары ключ: значение не имеют двойных кавычек, а модуль JSON не любит его при попытке декодирования.

Ответы [ 2 ]

0 голосов
/ 28 октября 2018

Вы можете попробовать использовать Cpanel :: JSON :: XS в расслабленном режиме или JSONY , чтобы проанализировать почти JSON, а затем записатьобычный JSON с использованием Cpanel :: JSON :: XS.В зависимости от того, что именно не так с вашими входными данными, те или иные могут понять это лучше.

use strict;
use warnings;
use Cpanel::JSON::XS 'encode_json';

# JSON is normally UTF-8 encoded; if you're reading it from a file, you will likely need to decode it from UTF-8
my $string = q<{foo: 1,bar:'baz',}>;

my $data = Cpanel::JSON::XS->new->relaxed->decode($string);
my $json = encode_json $data;
print "$json\n";

use JSONY;
my $data = JSONY->new->load($string);
my $json = encode_json $data;
print "$json\n";
0 голосов
/ 27 октября 2018

Есть несколько подходов, чтобы обойти это.

Если вы собираетесь использовать группы захвата:

  • При захвате полноты каждого пункта чередования.
    Объедините группы захвата в 1 и переместите группу наружу.

     (                             # (1 start)
          (?<! ["\w] )
          \w+ 
          (?= : )
       |  
          (?<= : )
          [\w\d\\.+=/]+ 
     )                             # (1 end)
    

    s/((?<!["\w])\w+(?=:)|(?<=:)[\w\d\\.+=\/]+)/"$1"/g

  • Используйте Сброс ветви конструкция (?| aaa ).
    Это приведет к тому, что группы захвата в каждом чередовании начнут нумеровать свои группы
    с той же точки.

     (?|
          (?<! ["\w] )
          ( \w+ )                       # (1)
          (?= : )
       |  
          (?<= : )
          ( [\w\d\\.+=/]+ )             # (1)
     )
    

    s/(?|(?<!["\w])(\w+)(?=:)|(?<=:)([\w\d\\.+=\/]+))/"$1"/g

  • Использовать Именованные группы захвата, которые можно использовать повторно (аналогично сбросу ветви).
    В каждом чередовании используйте одни и те же имена. Сделайте группу, которая не релевантна, пустой группой.
    Это работает с использованием name в подстановке вместо числа.

        (?<! ["\w] )
        (?<V1> \w+ )                  # (1)
        (?<V2> )                      # (2)
        (?= : )
     |  
        (?<= : )
        (?<V1> )                      # (3)
        (?<V2> [\w\d\\.+=/]+ )        # (4)
    

    s/(?<!["\w])(?<V1>\w+)(?<V2>)(?=:)|(?<=:)(?<V1>)(?<V2>[\w\d\\.+=\/]+)/"$+{V1}$+{V2}"/g


Можно объединить две концепции именованной замены и сброса ветви
если чередование содержит более 1 группы захвата.
В приведенном ниже примере используются номера групп захвата.

Теория состоит в том, что вы помещаете фиктивных групп захвата в каждом чередовании на
«дополняют» ветку, чтобы равняться наибольшему количеству групп за одно чередование.

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

 (?|                    # Branch Reset
                             # ------ Br 1 --------
      ( )                    # (1)
      ( \d{4} )              # (2)
      ABC294
      ( [a-f]+ )             # (3)
   |  
                             # ------ Br 2 --------          
      ( :: )                 # (1)
      ( \d+ )                # (2)
      ABC555
      ( )                    # (3)
   |  
                             # ------ Br 3 --------
      ( == )                 # (1)
      ( )                    # (2)
      ABC18888
      ( )                    # (3)
 )

s/(?|()(\d{4})ABC294([a-f]+)|(::)(\d+)ABC555()|(==)()ABC18888())/"$1$2$3"/g

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