2013-09-12 4 views
1

Как я могу сопоставить путь, только если нет? плюс ноль или больше символов на конце.Regex соответствует любому символу NOT, за которым следует «что-то»

У меня есть следующий путь:

/something/contentimg/coast03.jpg?itok=ABC 

Я хочу имя файла, но только если нет «что?», После расширения файла.

Я пробовал:

/^.*\/(.*)(?!\?.*)$/ 

Но он совпадает в любом случае. Это результат. Что я делаю не так?

Array 
(
    [0] => /something/contentimg/coast03.jpg?itok=ABC 
    [1] => coast03.jpg?itok=ABC 
) 

Использование php.

+0

Несвязанный, но полезный намек: когда вы встречаете путь, вы должны обернуть свой узор чем-то, кроме перекоса. Тогда вам не нужно скрывать косые черты, сохраняя ваш шаблон поиска более разборчивым: '# ^. */(. *) (?! \?. *) $ #' –

+1

На каком языке вы используете? – sinsedrix

ответ

0
^.*\/([^?]+)(?![?].+)$ 

Рабочая DEMO

Ваше выражение не работает, потому что (.*) матчи все после последнего \, так что нет ничего, что можно было бы рассматривать как отрицательный вход опережения.

+1

Вы можете полностью потерять внешний вид, это не служит никакой цели. – Jon

3

Использование parse_url:

print_r(parse_url('/something/contentimg/coast03.jpg?itok=ABC')) 

(
    [path] => /something/contentimg/coast03.jpg 
    [query] => itok=ABC 
) 
1

* квантор ведет себя жадно и спички все до конца регулярного выражения, поэтому негативные пинки в при касательно последующего окончания ввода (и, конечно, не найти то, что он ищет). Регулярное выражение должно быть сделано немного по-другому:

/^.*\/([^?]+)$/ 

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

+0

На самом деле, $ соответствует концу строки, а не концу строки. – pguardiario

+0

@pguardiario: На самом деле ни технически не корректно, потому что '$' соответствует либо концу, либо перед новой строкой, которая является последним символом. Вам нужно явно перейти в многострочный режим с '/ m' или' PCRE_MULTILINE', чтобы он соответствовал встроенным символам новой строки, поэтому в IMO описание в порядке. Я не хочу быть «или до окончания новой строки» педантичным, потому что он не имеет абсолютно никакой цели в контексте ответа. – Jon

+0

Это не нормально. $ соответствует концу строки. Говорить, что $ match конец строки неверен, и я просто исправляю вас. – pguardiario

0

Это, как это в настоящее время соответствие:

.* - взахлеб матчей до до последнего / - /something/contentimg
\/ - соответствует /
(.*) - совпадает с остальной частью строки - coast03.jpg?itok=ABC
(?!\?.*) - проверяет, что следующие символы не совпадают, так как мы уже в конце, это явно не будет соответствовать.

Что вы должны сделать:

Похоже, вы можете просто проверить, если ? существует в строке, так что попробуйте:

/^(?!.*\?)/ 

Или матч до последнего /, а затем проверить для ? оттуда:

/^(?!.*\/.*\?)/ 

Пояснение:

Вы уже знаете, что (?!...) отрицательный прогноз, вы просто не совсем уверены, как его использовать. Куда бы вы ни поместили его, он изо всех сил пытается сопоставить данный шаблон с этой позиции. Если это удается, регулярное выражение не совпадает. Поэтому было бы неплохо поставить это в самом начале и попытаться сопоставить остальную часть строки.

Так основной формат для этого примера:

/^(?!...).*$/ 

где (?!...) содержит шаблон для строк, которые вы хотите исключить .

.*$ в конце не требуется, и если вы хотите проверить всю строку, запомните $ в конце ожидания.

/^(?!...$)/ 
Смежные вопросы