2013-09-19 3 views
-2

Предположим, у меня есть список символов [a, b, c], и я хочу написать регулярное выражение, так что любая строка принимается, если она имеет все элементы в списке символов по крайней мере один раз и символы могут отображаться в любом порядке в строке.Regex без ордера

Пример принятых строк

abc, aabbbc, bbaac, cab

Пример строк не accepteed

aaabb, bab, caa, aacd, deeff

+1

Любая конкретная причина, вы хотите использовать Regex для этого? – Hubro

+0

'a + b + c + | a + c + b + | c + b + a + | ....' :)) – quetzalcoatl

+0

Может ли строка содержать все символы из списка, а также другие? например является ли «abcd» действительным? – mikej

ответ

3

Setsмного больше подходит для этой цели, чем регулярные выражения. То, что вы действительно пытаетесь сделать, это выяснить, является ли (a, b, c) действительным подмножеством ваших различных строк. Вот пример того, как сделать это в Ruby:

 
> require "set" 
=> true 
> reference = Set.new("abc".split("")) 
=> #<Set: {"a", "b", "c"}> 
> test1 = Set.new("aabbbc".split("")) 
=> #<Set: {"a", "b", "c"}> 
> test2 = Set.new("caa".split("")) 
=> #<Set: {"c", "a"}> 
> reference.subset? test1 
=> true 
> reference.subset? test2 
=> false 
+0

Спасибо за помощь ... – arpanchaudhury

2

Рассмотрим, прежде чем читать дальше: Rege xes: not always the best way для решения проблемы. Если вы рассматриваете регулярное выражение, но это не очевидно или просто для продолжения, вы можете остановиться и подумать, есть ли удобное решение без регулярного выражения.

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


На основе документации, я считаю, что Рубин поддерживает позитивные lookaheads (также известные как нулевую ширину утверждений). Будучи в первую очередь программистом .NET, я не знаю Ruby достаточно хорошо, чтобы сказать, поддерживает ли он или не поддерживает фиксированные длины (он не встречается во всех вариантах regex), но если это так, вы можете легко применить три разных вида в начале вашего выражения, чтобы найти каждый из шаблонов или символов, которые необходимо:

^(?=.*a)(?=.*b)(?=.*c).* 

Это не сработает, если какой-либо один из lookaheads не проходит. Этот подход потенциально чрезвычайно эффективен, потому что вы можете иметь сложные подвыражения в своем представлении. Например:

^(?=.*a[bc]{2})(?=.*-\d)(?=.*#.{3}%).* 

будет проверить, что входное содержит follwed два символов, каждый из которых либо б или с, А - следует любой цифра и #, за которым следуют любые три символа, за которыми следует %, в любом конкретном порядке. Таким образом, следующие строки будут проходить:

#acb%-9 
#-22%abb 

Этот вид сложного сопоставления с образцом трудно сжато дублировать.


Чтобы решить эту проблему comment:

Нет, не может быть ...так ABCD не принято

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

^(?=.*a)(?=.*b)(?=.*c)(?!.*[^abc]).* 

(As noted by Gene, то .* на конец не нужен ... Возможно, я должен был упомянуть об этом. Это просто на случай, если вы действительно хотите выбрать текст)

+1

Пример был бы полезен. –

+0

Тэги say RUBY, а не IronRuby – quetzalcoatl

+0

@JoachimIsaksson - Да ... с тремя закрытыми голосами мне нужно было что-то публиковать ... – JDB

1
def acceptable? s 
    s =~ /(?=.*a)(?=.*b)(?=.*c)/ 
end 

acceptable? 'abc'  # => 0 
acceptable? 'aabbbc' # => 0 
acceptable? 'bbaac' # => 0 
acceptable? 'cab'  # => 0 
acceptable? 'aaabb' # => nil 
acceptable? 'bab'  # => nil 
acceptable? 'caa'  # => nil 
acceptable? 'aacd' # => nil 
acceptable? 'deeff' # => nil 
acceptable? 'abcd' # => 0 
0

регулярное выражение, которое соответствует только определенные символы могли бы быть так:

(?=[bc]*a)(?=[ac]*b)(?=[ab]*c)[abc]* 
+0

Huh ... interesting. Кроме того, что он по-прежнему будет соответствовать 'abcd', который [он должен * не * делать] (http://stackoverflow.com/questions/18900788/regex-without-order#comment27899734_18900788). – JDB

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