2016-03-07 5 views
1

Я хотел бы написать регулярное выражение (я использую MATLAB), чтобы найти последовательность «a», но отклонить случаи, когда вся строка содержит изолированный символ «x», то есть «x», (включая пространство), где 'x' используется как разделитель для a и b).Регулярное выражение, которое исключает некоторые

Вот несколько примеров, о которых я могу думать.

  • 'a': матч 'a'.
  • 'a b': матч 'a'.
  • 'b a': соответствие 'a'.
  • 'a x b': не соответствуют 'a' (потому что a и b разделены x).
  • 'bxa': не соответствуют 'a' (поскольку b и a разделены символом x)
  • 'a xb': соответствие 'a' (поскольку xb не совпадает с изолированным символом x, используемым для отдельные слова).

ответ

2

Fun вопрос. Я добавлю несколько тестовых примеров, которые, по моему мнению, необходимы, чтобы проблема была хорошо указана. Надеюсь, это то, что вы намеревались.

Тестовые данные:

s = {'a', ... %// match 
    'a b', ... %// match 
    'b a', ... %// match 
    'a x b', ... %// don't 
    'b x a', ... %// don't 
    'a xb', ... %// match 
    'ab', ... %// don't match 
    'ba' ... %// don't match 
    } ; 

Регулярное выражение:

ind = cellfun(@(x) ~isempty(regexp(x,'^a(?=\s)|(?<=\s)a$|^a$|(?<=\s)(a)(?=\s)')),s) ... 
& cellfun(@(x) isempty(regexp(x,'(?<=\s)x(?=\s)')),s) 

ind = 

    1  1  1  0  0  1  0  0 

>> s(ind) 

ans = 

    'a' 'a b' 'b a' 'a xb' 

Объяснение:

Посмотрите на строки, содержащие x, где матч предшествует спа ce ((?<=\s)) и затем пробел ((?=\s). Исключить их.

Посмотрите на строки, которые либо начинаются с a с последующим пробелом (^a(?=\s)), или которые заканчиваются в a и предшествует пробел ((?<=\s)a$), или которые точно a без каких-либо других символов (^a$), или которые содержат a, оба предшествуют пробелу ((?<=\s)(a)(?=\s)). Совместите их.

+0

Спасибо за помощь! – Marca85

0

Если вы используете Matlab, тогда у вас есть лучшие альтернативы, чем регулярное выражение. Но если вы настаиваете, то вы можете использовать lookarounds:

(?<!.\bx\b.)a(?!.\bx\b.) 
+0

'regexp ('a x b', '(?

+0

@ LuisMendo, который будет соответствовать, например, 'x a v', что не очень хорошо. – Maroun

+0

Хм, на самом деле я думаю, что не понимаю вопроса –

1

Давайте брать тестовые случаи @transversality условие и добавить несколько дополнительных:

s = {'a', ... %// match 
    'a b', ... %// match 
    'b a', ... %// match 
    'a x b', ... %// don't 
    'b x a', ... %// don't 
    'a xb', ... %// match 
    'ab', ... %// don't match 
    'ba', ... %// don't match 
    'x a', ... %// don't match 
    'a x' ... %// don't match 
    } ; 

Это решение не использовать lookarounds вообще. Вместо этого он использует anchors:

ind = cellfun(@(x) ~isempty(regexp(x, '\<a\>', 'once')), s) ... 
    & cellfun(@(x) isempty(regexp(x,'\<x\>', 'once')), s) 

Это просто находит строки, содержащие a, где a является и в начале и в конце слова (и слово представляет собой непрерывную последовательность алфавитно-цифровых символов), а не содержащую изолированную x.

В отличие от теста tc, последние два случая не соответствуют этому тесту (но, возможно, они должны? OP не указали ...).

+0

Очень круто. Узнал новый трюк, спасибо! –

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