Использование Regex для поиска строки, содержащей «http://"» и не содержащей «mysite.com» - PullRequest
0 голосов
/ 14 марта 2012

как мне написать регулярное выражение для поиска строки, содержащей "http://" И не содержащей" mysite.com "?

Ответы [ 2 ]

6 голосов
/ 14 марта 2012

ПРЕДУПРЕЖДЕНИЕ

Попытка связать регулярные выражения в булеву логику, наилучшим образом достижимая в правильном языке программирования, является неблагодарной работой.Хотя можно написать /PAT1/ and not /PAT2/, используя сложные взгляды, так что это всего лишь один шаблон, но это трудная задача. Вы не должны делать это таким образом!

Вы должны были объяснить, что вы действительно делали в первую очередь - какая-то операция сопоставления в текстовом редакторе.Вы не сделали.Таким образом, вы получите общий ответ, который будет сложно адаптировать к вашей локализованной ситуации.

Быстрый ответ

(?sx)                 # let dot cross newlines, enable comments & whitspace
(?= .* http://     )  # lookahead assertion for http://
(?! .* mysite\.com )  # lookahead negation  for mysite.com

Используя синтаксис Perl, вы можете придерживаться этого (предварительно) скомпилированного шаблонав переменную для использования в будущем следующим образом:

my $is_valid_rx = qr{
    (?= .* http://     )  # lookahead assertion for http://
    (?! .* mysite\.com )  # lookahead negation  for mysite.com
}sx;                      # /s to cross newlines, /x for comments & whitespace

# then later on…
if ($some_string =~ $is_valid_rx) { 
     # your string has an http blah and lacks a mysite blah
}

Однако, если ваша цель состоит в том, чтобы вытянуть все такие ссылки, это не поможет вам, потому что эти упреждающие подсказки не говорят вам, где вstring Ваша ссылка встречается.

В этом случае намного проще написать что-то, чтобы вытащить ссылки, а затем отфильтровать нежелательные случаи, используя два отдельных регулярных выражения вместо попытки заставить все делать.

 @all_links = ($some_string =~ m{ https?://\S+ }xg);
 @good_links = grep !/mysite\.com/, @all_links;

Обратите внимание, что не делается попытка сопоставить только ссылки, содержащие действительные символы URL, или что нет случайной конечной пунктуации, как это часто происходит в простом тексте.

А теперь, дляреальный ответ

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

Здесь, напротив, полная программа, которая выводит все <a ...> и <img ...> ссылаются на адреса в своих аргументах URL и фактически делают это правильно, потому что используют реальный синтаксический анализатор.

#!/usr/bin/env perl
#
# fetchlinks - fetch all <a> and <img> links from listed URL args
# Tom Christiansen <tchrist@perl.com>
# Wed Mar 14 08:03:53 MDT 2012
#
use strict;
use warnings;

use LWP::UserAgent;
use HTML::LinkExtor;
use URI::URL;

die "usage: $0 url ...\n" unless @ARGV;

for my $arg (@ARGV) {
    my @links = fetch_wanted_links($arg => qw<a img>);
    for my $link (@links) {
        print "$arg => " if @ARGV > 1;
        print "$link\n";
    }
}

exit;

sub fetch_wanted_links {
    my($url, @wanted) = @_;

    my %wanted;
    @wanted{@wanted} = (1) x @wanted;

    my $agent = LWP::UserAgent->new;

    # Set up a callback that collect links of the wanted variety
    my @hits = ();

    # Make the parser.  Unfortunately, we don't know the base yet
    # (it might be different from $url)
    my $parser = new HTML::LinkExtor sub {
       my($tag, %attr) = @_;
       return if %wanted and not $wanted{$tag};
       push @hits, values %attr;
    };

    # Request document and parse it as it arrives
    my $response = $agent->request(
           HTTP::Request->new(GET => $url),
           sub { $parser->parse( $_[0] ) },
    );

    # Expand all image URLs to absolute ones
    my $base = $response->base;
    @hits = map { $_ = url($_, $base)->abs } @hits;
    return @hits;
}

Если вы запускаете его на таком URL-адресе, он дает этот учет всехссылки на якорь и изображения:

$ perl fetchlinks http://www.perl.org/
http://www.perl.org/
http://st.pimg.net/perlweb/images/camel_head.v25e738a.png
http://www.perl.org/
http://www.perl.org/learn.html
http://www.perl.org/docs.html
http://www.perl.org/cpan.html
http://www.perl.org/community.html
http://www.perl.org/contribute.html
http://www.perl.org/about.html
http://www.perl.org/get.html
http://www.perl.org/get.html
http://www.perl.org/get.html
http://www.perl.org/about.html
http://www.perl.org/learn.html
http://st.pimg.net/perlweb/images/icons/learn.v0e1f83c.png
http://www.perl.org/learn.html
http://www.perl.org/community.html
http://st.pimg.net/perlweb/images/icons/community.v03bf8ce.png
http://www.perl.org/community.html
http://www.perl.org/docs.html
http://st.pimg.net/perlweb/images/icons/docs.v2622a01.png
http://www.perl.org/docs.html
http://www.perl.org/contribute.html
http://st.pimg.net/perlweb/images/icons/cog.v08b9acc.png
http://www.perl.org/contribute.html
http://www.perl.org/dev.html
http://www.perl.org/contribute.html
http://www.perl.org/cpan.html
http://st.pimg.net/perlweb/images/icons/cpan.vdc5be93.png
http://www.perl.org/cpan.html
http://www.perl.org/events.html
http://st.pimg.net/perlweb/images/icons/cal.v705acef.png
http://www.perl.org/events.html
http://www.perl6.org/
http://st.pimg.net/perlweb/images/icons/perl6.v8ff6c63.png
http://www.perl6.org/
http://www.perl.org/dev.html
http://www.perlfoundation.org/
http://st.pimg.net/perlweb/images/icons/onion.vee5cb98.png
http://www.perlfoundation.org/
http://www.cpan.org/
http://search.cpan.org/~jtang/Net-Stomp-0.45/
http://search.cpan.org/~vaxman/Array-APX-0.3/
http://search.cpan.org/~salva/Net-SFTP-Foreign-1.71/
http://search.cpan.org/~grandpa/Win32-MSI-HighLevel-1.0008/
http://search.cpan.org/~teejay/Catalyst-TraitFor-Component-ConfigPerSite-0.06/
http://search.cpan.org/~jwieland/WebService-Embedly-0.04/
http://search.cpan.org/~mariab/WWW-TMDB-API0.04/
http://search.cpan.org/~teejay/SOAP-Data-Builder-1/
http://search.cpan.org/~dylan/WWW-Google-Translate-0.03/
http://search.cpan.org/~jtbraun/Parse-RecDescent-1.967_008/
http://www.perl.org/get.html
http://www.perl.org/learn.html
http://www.perl.org/docs.html
http://www.perl.org/community.html
http://www.perl.org/events.html
http://www.perl.org/siteinfo.html#sponsors
http://www.yellowbot.com/
http://st.pimg.net/perlweb/images/friends/yellowbot.vcc29f5b.gif
http://www.perl.org/
http://blogs.perl.org/
http://jobs.perl.org/
http://learn.perl.org/
http://dev.perl.org/
http://creativecommons.org/licenses/by-nc-nd/3.0/us/
http://i.creativecommons.org/l/by-nc-nd/3.0/us/80x15.png
http://www.perl.org/siteinfo.html

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

0 голосов
/ 14 марта 2012

Попробуйте что-то вроде /http:\/\/(?!mysite.com)/ (стиль perl, работа также в javascript)

...