2012-05-29 2 views
4

Я пытаюсь разобрать имена продуктов, которые имеют несколько аббревиатур для размеров. Например, среда может бытьРегулярное выражение соответствует слову «1» длиной

m, medium, med 

Я попытался простой

preg_match('/m|medium|med/i',$prod_name,$matches); 

, который отлично работает для «продукта м АБВ». Однако, когда я пытаюсь «product s/m abc», я получаю ложноположительное совпадение. Я также попытался

preg_match('/\bm\b|\bmedium\b|\bmed\b/i',$prod_name,$matches); 

, чтобы заставить его найти в слове, но м с/м по-прежнему совпадают. Я предполагаю, что это связано с тем, что двигатель обрабатывает «/» в названии как разделитель слов?

Итак, чтобы подвести итог, мне нужно совместить 'm' в строке, но не 's/m' или 'small' и т. Д. Любая помощь приветствуется.

ответ

6
%\b(?<![/-])(m|med|medium)(?![/-])\b% 

Вы можете использовать отрицательное или предпросмотр 'назад, чтобы исключить обижая сепараторы. Это означает "m"/"med"/"medium", который является его собственным словом, но не предшествует или не следует ни косой чертой, ни чертой. Он также работает в начале и в конце строки, так как отрицательный lookahead/lookbehind не заставляет присутствовать соответствующий символ.

Если вы хотите, чтобы разграничить на пробельных, вы можете использовать позитивный вариант:

%\b(?<=\s|^)(m|med|medium)(?=\s|$)\b% 

("m"/"med"/"medium" который предшествует пробел или в начале строки, а затем пробел или конец строка)

+0

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

+1

@BenRoux: Предоставлено. Я предложу альтернативную форму. – Amadan

+0

Малый вопрос о последующих действиях. Кажется, я получаю дубликаты, используя это выражение, используя preg_match (например, result: array ([0] => med [1] => med)). Любые идеи о том, почему? Не проблема, просто попытка улучшить понимание моего регулярного выражения. – Conor

0

Попробуйте это, оно должно соответствовать medium, med и m.

medium|med|^m$ 
+0

Это соответствует только '«м»' (один только буква М в строке), но не '«рубашка м мужской»'. – Amadan

+0

должен быть '^ medium | med | m $' –

+0

@AhmedJolani: Это будет соответствовать строкам, которые начинаются с 'medium', строк, содержащих' med', и строк, заканчивающихся 'm'. – Ryan

1

Я всегда думаю об этих вещах в ERE. И в соответствии с re_format(7) границы слова ERE, [[:<:]] и [[:>:]] соответствуют нулевой строке в начале и конце слова соответственно. Так что ... так PREG должны понимать ERE обозначения, я мог бы пойти с:

/[[:<:]](m(ed(ium)?)?)[[:>:]]/ 

Или для более легкого чтения, может быть:

/[[:<:]](m|med|medium)[[:>:]]/ 

В PHP, хотя, вы можете использовать PREG вместо ЭРД. В PREG, \b указывает на границу слова, так:

preg_match('/\b(m(ed(ium)?)?)\b/', $prod_name, $matches);