Как я могу эффективно обработать несколько операций поиска/замены Perl на той же строке?

На application(didFinishLaunchingWithOptions:) URL находится внутри опций. Пожалуйста, проверьте это снова.

Apple docs: launchOptions Словарь, указывающий причину запуска приложения (если есть). Содержимое этого словаря может быть пустым в ситуациях, когда пользователь запускает приложение напрямую. Информацию о возможных ключах в этом словаре и о том, как их обрабатывать, смотрите в разделе Параметры запуска ключей.

https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622921-application

5
задан brian d foy 9 May 2009 в 20:43
поделиться

3 ответа

Problem #1

As there doesn't appear to be much structure shared by the individual regexes, there's not really a simpler or clearer way than just listing the commands as you have done. One common approach to decreasing repetition in code like this is to move $text into $_, so that instead of having to say:

$text =~ s/foo/bar/g;

You can just say:

s/foo/bar/g;

A common idiom for doing this is to use a degenerate for() loop as a topicalizer:

for($text)
{
  s/foo/bar/g;
  s/qux/meh/g;
  ...
}

The scope of this block will preserve any preexisting value of $_, so there's no need to explicitly localize $_.

At this point, you've eliminated almost every non-boilerplate character -- how much shorter can it get, even in theory?

Unless what you really want (as your problem #2 suggests) is improved modularity, e.g., the ability to iterate over, report on, count etc. all regexes.

Problem #2

You can use the qr// syntax to quote the "search" part of the substitution:

my $search = qr/(<[^>]+>)/;
$str =~ s/$search/foo,$1,bar/;

However I don't know of a way of quoting the "replacement" part adequately. I had hoped that qr// would work for this too, but it doesn't. There are two alternatives worth considering:

1. Use eval() in your foreach loop. This would enable you to keep your current %rxcheck2 hash. Downside: you should always be concerned about safety with string eval()s.

2. Use an array of anonymous subroutines:

my @replacements = (
    sub { $_[0] =~ s/<[^>]+>/ /g; },
    sub { $_[0] =~ s/\s+/ /g; },
    sub { $_[0] =~ s/[\(\{\[]\d+[\(\{\[]/ /g; },
    sub { $_[0] =~ s/\s+[<>]+\s+/\. /g },
    sub { $_[0] =~ s/\s+/ /g; },
    sub { $_[0] =~ s/\.*\s*[\*|\#]+\s*([A-Z\"])/\. $1/g; },
    sub { $_[0] =~ s/\.\s*\([^\)]*\) ([A-Z])/\. $1/g; }
);

# Assume your data is in $_
foreach my $repl (@replacements) {
    &{$repl}($_);
}

You could of course use a hash instead with some more useful key as the hash, and/or you could use multivalued elements (or hash values) including comments or other information.

10
ответ дан 18 December 2019 в 09:10
поделиться

Хеши не подходят, потому что они неупорядочены. Я нахожу массив массивов, второй массив которых содержит скомпилированное регулярное выражение и строку для eval (на самом деле это двойной eval), работает лучше всего:

#!/usr/bin/perl

use strict;
use warnings;

my @replace = (
    [ qr/(bar)/ => '"<$1>"' ],
    [ qr/foo/   => '"bar"'  ],
);

my $s = "foo bar baz foo bar baz";

for my $replace (@replace) {
    $s =~ s/$replace->[0]/$replace->[1]/gee;
}

print "$s\n";

Я думаю, что второе решение j_random_hacker значительно превосходит мое. Отдельные подпрограммы обеспечивают максимальную гибкость и на порядок быстрее, чем мое решение / ee :

bar <bar> baz bar <bar> baz
bar <bar> baz bar <bar> baz
         Rate refs subs
refs  10288/s   -- -91%
subs 111348/s 982%   --

Вот код, который производит эти числа:

#!/usr/bin/perl

use strict;
use warnings;

use Benchmark;

my @subs = (
    sub { $_[0] =~ s/(bar)/<$1>/g },
    sub { $_[0] =~ s/foo/bar/g },
);

my @refs = (
    [ qr/(bar)/ => '"<$1>"' ],
    [ qr/foo/   => '"bar"'  ],
);

my %subs = (
    subs => sub {
        my $s = "foo bar baz foo bar baz";
        for my $sub (@subs) {
            $sub->($s);
        }
        return $s;
    },
    refs => sub {
        my $s = "foo bar baz foo bar baz";
        for my $ref (@refs) {
            $s =~ s/$ref->[0]/$ref->[1]/gee;
        }
        return $s;
    }
);

for my $sub (keys %subs) {
    print $subs{$sub}(), "\n";
}

Benchmark::cmpthese -1, \%subs;
4
ответ дан 18 December 2019 в 09:10
поделиться

Вы говорите, что имеете дело с HTML. Теперь вы понимаете, что это в значительной степени проигрышная битва с мимолетными и хрупкими решениями.

Правильный синтаксический анализатор HTML облегчил бы вашу жизнь. HTML :: Parser может быть трудным в использовании, но есть и другие очень полезные библиотеки на CPAN , которые я могу порекомендовать, если вы можете указать , что вы пытаетесь сделать а не как .

4
ответ дан 18 December 2019 в 09:10
поделиться
Другие вопросы по тегам:

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