2013-07-19 5 views
1

У меня есть регулярное выражение, которое улавливает ключевое слово, которое приходит после знака номера:Как я могу сопоставить определенную строку, которая не содержит звездочку?

/^#\s*([a-zA-Z\-\s]+)/ 

Однако, мне нужно изменить регулярное выражение, чтобы указать не матч строку, содержащую звездочку. Например, мне нужно регулярное выражение для соответствия # keyword, но не# *keyword.

Следующая моя лучшая попытка решить эту:

/^#\s[^[*]]*([a-zA-Z\-\s]+)/ 

Я новенький на Perl, поэтому я уверен, что решение очень простое, но мое время, проведенное исследование и методом проб и ошибок Ждут» Мне очень помогает.

+1

Будет ли звездочка всегда находиться в начале ключевого слова? – Luke

+0

Люк, он всегда будет в начале. –

+0

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

ответ

3

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

/^#\s*([a-zA-Z\-\s]+)/ 

Это будет по-прежнему соответствовать что-то вроде:

# key*word 

. .. хотя только key будет соответствовать. Одно из решений, если вы уверены, что только ключевое слово будет занимать остальную часть линии, было бы заставить только белый список символов не появляться до конца строки, например:

/^#\s*([a-zA-Z\-\s]+)$/ 

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

/^#\s*([a-zA-Z\-]+)(?:\s|$)/ 

Это будет соответствовать:

# keyword foo 

И это будет матч:

# keyword 

Но это не будет соответствовать:

# key*word foo 

Nor:

# key*word 

Nor:

# key* word foo 

Nor:

# **** keyword 
+0

Неправильно - я совершил ту же ошибку. Это из-за \ s внутри класса символов. – Dan

+0

Мое первое регулярное выражение фиксирует нулевое значение для моего ключевого слова. По какой-то причине он соответствует «# **** ключевому слову», и я хочу конкретно сказать, что он не соответствует звездочке. Я, вероятно, объясняю это очень плохо ... –

+0

ОК, он будет соответствовать вещам * до * звездочки, но он не будет соответствовать самой звездочке. – Jez

1

я считать, что проблема в том, что вы подходите частично для строк со звездочкой, например:

foobar* => matching string "foobar" 

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

/^#\s*(?!.*\*)(.+)/ 

Это .*\* утверждает, что ни звездочка не появляется в любом месте перед знаком фунта.Это, однако, только причудливый способ сделать две вещи в одном:

if (!/\*/ && /^#\s*(.+)/) { ... 
1

соответствия Попробуйте использовать это регулярное выражение:

^#\s*([-a-zA-Z]+)(?=\s|$) 

Ваше регулярное выражение уже не соответствует # *keyword, но это регулярное выражение удалена пробел из захваченной группы и использует взгляд вперед, чтобы утверждать, что символ, следующий за словом, не является звездочкой, поэтому он не будет соответствовать # key*word.

Также обратите внимание на это небольшое упрощение отсутствия необходимости избегать тире, когда это первый (или последний) символ в классе символов.

См. live demo этого на рублевом.

+0

Экранирование тире выглядит более четким. – Jez

+0

@Jez Я «код меньше хорош». Для меня избегайте char = code noise, и я так хорошо знаком с этим правилом, что для меня не ускользает на самом деле заметно яснее (с умением мысленно я должен игнорировать обратную косую черту, на которую я нахожу больше усилий, просто читая тире) – Bohemian