Regex Извлечение символов внутри WUB - PullRequest
1 голос
/ 18 апреля 2020

Я хочу регулярное выражение, которое извлекает все слова внутри "WUB", но не нашло никакого решения! например, он будет извлекать из "WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB"

следующие строки (без кавычек) ["WE", "ARE", "THE", "CHAMPIONS"]

вот что я пробовал до сих пор:

((?:.(?!WUB))+) Но это дает мне следующий вывод (из примера выше):

['WUBW', 'WUBAR', 'WU', 'WUBTH', 'WUBCHAMPION', 'WUBM', 'WUBFRIEN', 'WUB']

Пожалуйста, помогите мне больше понять эту проблему

Ответы [ 3 ]

3 голосов
/ 18 апреля 2020
$str =~ / WUB \K (?:(?!WUB).)+ (?=WUB) /sxg

или

$str =~ / (?<=WUB) (?:(?!WUB).)+ (?=WUB) /sxg    # Probably slower.

Начиная после WUB, без фактического включения WUB в совпадение (\K), найдите один или несколько символов, которые не являются началом WUB. Убедитесь, что за ним следует WUB ((?=WUB)).


Если строка всегда будет начинаться и заканчиваться WUB, или если вы не возражаете против получения текста до первого WUB и после последнего WUB следующее намного яснее и, безусловно, быстрее:

grep length, split /WUB/, $str
0 голосов
/ 18 апреля 2020

Еще один способ сделать это, используя split:

my $str = "WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB";

# grep is here to remove empty elements
my @list = grep length, split /WUB/, $str;
say Dumper\@list;

Вывод:

$VAR1 = [
          'WE',
          'ARE',
          'THE',
          'CHAMPIONS',
          'MY',
          'FRIEND'
        ];

Тест:

use Modern::Perl;
use Benchmark qw(:all);

my $str = "WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB";

my $count = -3;
cmpthese($count, {
    'match' => sub {
        my @list = $str =~  / WUB \K (?:(?!WUB).)+ (?=WUB) /sxg;
    },
    'split' => sub {
        my @list = grep length, split /WUB/, $str;
    },
});

Выход:

          Rate match split
match  57806/s    --  -54%
split 126455/s  119%    --
0 голосов
/ 18 апреля 2020

Простое выражение REGEX без утверждений о предварительном просмотре / обратном просмотре:

 /WUB((?:[^W]|W[^U]|WU[^B])+)/g

Предполагается, что тестируемая строка заканчивается WUB. Если это не так, вы должны либо включить в конец нулевое упреждающее утверждение (? = WUB),

 /WUB((?:[^W]|W[^U]|WU[^B])+)(?=WUB)/g

, либо удалить любые символы за последним WUB перед использованием регулярного выражения.

 s/WUB(?:[^W]|W[^U]|WU[^B])+$/WUB/

.

#! /usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my $s = "WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB";

print Dumper ([$s =~ /WUB((?:[^W]|W[^U]|WU[^B])+)/g]);

распечатывает:

$VAR1 = [
          'WE',
          'ARE',
          'THE',
          'CHAMPIONS',
          'MY',
          'FRIEND'
        ];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...