2013-07-28 2 views
1

у меня есть данные, как такpreg_match в фигурных скобках с необязательным существование дополнительного содержимого в фигурных скобках иногда

$data = '<a href="not important"><span class="theclass">data (not important)</span></a> <span class="anotherclass">extra data (October 1, 2010)</span>'; 

я хочу, чтобы получить дату в фигурных скобках, так ив сделал следующее preg_match

preg_match("/\((([a-zA-Z]{5,10} .*?)|(\d{4}))\)/i",$data,$res); 

, пожалуйста, не что иногда «1 октября» нет, НО ГОД ВСЕГДА ПРЕДСТАВЛЯЕТ, следовательно, условие ИЛИ ... вещь в этом случае дает мне массив из 3, я знаю его из-за набора из трех брекетов, которые у меня есть для каждого условие, есть ли другой лучший и более чистый способ достичь этого?

второе условие метод

$data = <a href="not important"><span class="theclass">data</span></a> <span class="theother">data <a href="not importand">data</a> (2009)</span> 
     </h3> 

Спасибо, ребята

+0

** Не используйте регулярные выражения для анализа HTML. Используйте подходящий модуль синтаксического анализа HTML. ** Вы не можете надежно проанализировать HTML с регулярными выражениями, и вы столкнетесь с печалью и разочарованием в будущем. Как только HTML изменится с ваших ожиданий, ваш код будет сломан. См. Http://htmlparsing.com/php для примеров того, как правильно анализировать HTML с PHP-модулями, которые уже были написаны, протестированы и отлажены. –

+0

, даже если я использую say xpath dom, мне все равно нужен класс ref by with, он может получить данные. это почти то же самое, что и с preg_match, задолго до нижнего прега, поэтому я не понимаю, почему люди против этого ... это то, что другие более легкие? – Anup

ответ

2

Используйте lookarounds

Здесь мы делаем, что есть предшествующий ( характер, то мы ищем текст мы видим в дата, отформатированная как ваш пример. Этот маленький код говорит ALLOW для буквенно-цифровых символов, символа пробела и запятой, а также цифр ([A-Za-z ,\d]+)?. Знак + означает не менее 1. Это не так жадно, как .* или .+. Я окружаю его скобкой, а затем добавляю символ ?, чтобы он не требовался. Он работает так же, как и ваш или логически, потому что он все равно найдет год, но мы не делаем PHP больше работы, анализируя еще одну проверку. Затем мы находим год (всегда 4 цифры {4}). Затем мы проверяем, чтобы за ним последовал буквальный номер ). Взгляд сзади (?<=\() и взгляд вперед (?=\)) найдет матч, но они не включены в результаты матчей, оставив ваш ответ чистым.

С preg_match() возвращает array(), мы ловим первый элемент массива. Если вы ищете несколько совпадений в одной строке, вы можете использовать preg_match_all.

$data = '<a href="not important"> 
    <span class="theclass">data (not important)</span></a> 
    <span class="anotherclass">extra data (October 1, 2010)</span> 
    <span class="anotherclass">extra data (2011)</span>'; 
$pattern = '!(?<=\()([A-Za-z ,\d]+)?[\d]{4}(?=\))!'; 
$res = preg_match_all($pattern,$data,$myDate); 

print_r($myDate[0]); 

выход

Array 
(
    [0] => October 1, 2010 
    [1] => 2011 
) 

Если вы ищете только на один матч вы бы изменить код для этого:

$res = preg_match($pattern,$data,$myDate); 

echo($myDate[0]); 

Выход

October 1, 2010 

Другой способ написать шаблон будет таким: мы удалили скобку (группировку) и модификатор плюс + с последующим условным ?, но оставили первый набор. Затем мы используем *, чтобы сделать его условным. Разница заключается в preg_match и preg_match_all, любые группы также хранятся в массиве. Поскольку это не группа, то она не будет хранить дополнительные элементы массива.

$pattern = '!(?<=\()[A-Za-z ,\d]*[\d]{4}(?=\))!'; 
+0

Я добавил дополнительное условие, что год ВСЕГДА присутствует. и не могли бы вы объяснить объяснение ур. спасибо :) – Anup

+0

ах хорошо, что работает, когда есть дата и год, но не только год :) – Anup

+0

ваш код отлично работает, когда присутствуют дата и год, но не только год :) - preg_match, способный отвечают требованиям моего состояния :) – Anup

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