2016-03-10 3 views
2

У меня есть 2 строки: A и B. Теперь любой из этих 2 может быть подстрокой другого. Для например:Perl: Как мы можем проверить, какая строка является подстрокой другого?

Case:1-- A = "abcdef" and B = "abc" //String B is Substring of A. 

или

Case:2-- A = "xyz" and B = "wxyza" // String A is Substring of B. 

Теперь я знаю о индексной функции

index($substr, $str) 

, но я не знаю, какой из них является подстрокой другой, поэтому не может пройти параметры.

Я сделал это, используя OR, где я проверяю оба случая, заменяя переменные.

Мне нужно только знать, что одна из строк является подстрокой другой. Но мне нужна лучшая техника для этого? Спасибо заранее!

+1

Как насчет проверки длины обеих строк перед 'index()'? –

+0

Что делать, если длина такая же? скажем, A = «abcd» B = «bcef», тогда я не смогу решить, какой из них следует передать подстрокой. –

+1

Что вы подразумеваете под «лучшей техникой»? В одной строке одно утверждение, наиболее эффективное, самое элегантное ...? – zdim

ответ

1

Вот простой способ отправить пару и получить строку, охватывающую другую, или undef.

($enclosing) = grep { /$s2/ && /$s1/ } ($s1, $s2); 

Вот способ, чтобы получить строки заказаны как ($inside, $enclosing) или получить пустой список

@sorted = sort { "$b$a" =~ /^$b.*$b/ <=> "$a$b" =~ /^$a.*$a/ } 
      grep { $s1 =~ /$s2/ || $s2 =~ /$s1/ } ($s1, $s2); 

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

В обоих случаях равные слова никоим образом не обозначаются как таковые, и я не вижу, как они могут быть.
Однако они содержат друг друга и, вероятно, могут быть обработаны таким же образом.
Единственное решение в этом ответе, которое поставляет это @mask ниже, устанавливается в (1,1) в этом случае.

Весь код здесь пробегает use warnings, который для краткости опущен.


Первоначально. Возвращает копию слова, которое находится внутри другого или undef.

($in) = map { /^($s1).*$s1|(^$s2).*$s2/ ? $1 // $2 :() } ("$s1$s2", "$s2$s1"); 

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

($sc) = map { /^($s1).*$s1|(^$s2).*$s2/ ? ($1 && 1) || ($2 && 2) :() } 
       ("$s1$s2", "$s2$s1"); 

$sc является 1, когда $s1 содержится в $s2 или 2, когда $s2 находится в $s1 или undef иным образом.


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

@mask = map { /^($s1.*$s1)|(^$s2.*$s2)/ ? 1 : 0 } ("$s1$s2", "$s2$s1"); 

@mask имеет (bool, bool) для того, слова ($s1, $s2) находятся внутри другой.

Это: (1,1) (равно), или (1,0) или (0,1) (для $s1 или $s2 внутри другого) или (0,0) (отдельной).

+0

хорошо, поэтому маска содержит 1,0, если s1 является подстрокой s2 справа? –

+0

Итак, моя цель - проверить, какой из них является субстратом другого. Я могу следовать за соглашением, например, если ответ 0, первый - это подстрока другого, и если ответ равен 1, наоборот. Но то, что вы сделали, помогает! –

+0

Нет, я бы просто добавил их на карту, и все. Спасибо btw;) –

3

@zdim один оператор

Выбейте себя,

print length($s1) > length($s2) 
    ? "s2 is @{[ index($s1,$s2) <0 && 'NOT ']}substr of s1" 
    : "s1 is @{[ index($s2,$s1) <0 && 'NOT ']}substr of s2"; 
+0

nice :) Это заявление _one_? : +1 – zdim

+0

@zdim это может быть. :) –

+0

неправильный ответ, когда строки равны –

1

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

my $c = ($sa =~ /$sb/) || (-1) *($sb =~ /$sa/); 

где 1 означает, что $ SB является зиЬзЬгами в $ са и -1 означает $ са является зиЬзЬгами в $ сб.

Смежные вопросы