2010-11-15 2 views
1

Я пытаюсь использовать regexp для синтаксического анализа строки поиска, которая время от времени может содержать специальный синтаксис. Синтаксис im ищет [специальное ключевое слово: значение], и я хочу, чтобы каждое совпадение помещалось в массив. Имейте в виду, что строка поиска будет содержать другой текст, который не предназначен для анализа.preg_match не возвращает ожидаемые результаты

$searchString = "[StartDate:2010-11-01][EndDate:2010-11-31]"; 
$specialKeywords = array(); 
preg_match("/\[{1}.+\:{1}.+\]{1}/", $searchString, $specialKeywords); 
var_dump($specialKeywords); 

Выход:

массив (1) {[0] => строка (43) "[StartDate: 2010-11-01] [EndDate: 2010-11-31]"}

Желаемая Выход:

массива (2) {[0] => строка() "[StartDate: 2010-11-01]"

[1] => строка() "[EndDate: 2010-11-01]"}

Пожалуйста, дайте мне знать, если я не достаточно ясно.

+1

Квантификатор '{1} 'бесполезно. – Gumbo

ответ

4

Ваших .+ матчи через границу между двумя [...] частями, поскольку он соответствует любому символу, и как многие из них, как это возможно. Вы можете быть более ограничительным, какие символы могут быть сопоставлены. Также {1} является избыточным и может быть отброшен.

/\[[^:]*:[^\]]*\]/ 

должен работать более надежно.

Объяснение:

\[  # match a [ 
[^:]* # match any number of characters except : 
:  # match a : 
[^\]]* # match any number of characters except ] 
\]  # match a ] 
+0

Спасибо, что это сработало отлично, мне пришлось использовать preg_match_all, чтобы получить массив правильно, но выражение было на месте. Еще раз спасибо –

+0

Можете ли вы вникнуть в более подробное объяснение. Я смущен, как '[^:] *' = 'соответствует любому количеству символов, кроме:'.Является ли '[^:] *' совпадением всех символов до ':', потому что ':' находится в регулярном выражении? –

+0

@Derek Adair: '[^:] *' соответствует как можно большему количеству символов '' '' '' ', поэтому он соответствует всем символам до (но не включая)': '. Это поведение не зависит от того, существует ли в регулярном выражении выражение ':' или нет, но, конечно, оно имеет смысл здесь. Это также помогает согласовать как можно быстрее, потому что для регулярного выражения никогда не нужно возвращаться. –

1

Попробуйте следующее:

$searchString = "[StartDate:2010-11-01][EndDate:2010-11-31]"; 
$specialKeywords = array(); 
preg_match_all("/\[\w+:\d{4}-\d\d-\d\d\]/i", $searchString, $specialKeywords); 

var_dump($specialKeywords[0]); 

Выходов:

array(2) { 
    [0]=> 
    string(22) "[StartDate:2010-11-01]" 
    [1]=> 
    string(20) "[EndDate:2010-11-31]" 
} 
+0

Ему нужна дата начала/окончания, а не 2 даты окончания – Webnet

+0

@Webnet Yeeea, я должен действительно * посмотреть * на выходе, прежде чем копировать/вставлять его в ответ. – meagar

+0

Спасибо за ответ, проблема, которую я вижу с выражением, которое вы указали, заключается в том, что значение не всегда будет в формате Y-m-d. –

1

Это:

$searchString = "[StartDate:2010-11-01][EndDate:2010-11-31]"; 
preg_match_all('/\[.*?\]/', $searchString, $match); 

print_r($match); 

дает ожидаемый результат, я не уверен, если он соответствует всем ограничениям.

+0

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

0

Используйте это регулярное выражение: "/\[(.*?)\:(.*?)\]{1}/", а также использовать preg_match_all, он будет возвращать

array(3) { 
    [0]=> 
    array(2) { 
    [0]=> 
    string(22) "[StartDate:2010-11-01]" 
    [1]=> 
    string(20) "[EndDate:2010-11-31]" 
    } 
    [1]=> 
    array(2) { 
    [0]=> 
    string(9) "StartDate" 
    [1]=> 
    string(7) "EndDate" 
    } 
    [2]=> 
    array(2) { 
    [0]=> 
    string(10) "2010-11-01" 
    [1]=> 
    string(10) "2010-11-31" 
    } 
} 
0
/\[.+?\:.+?\]/ 

Я предлагаю этот метод, менее сложный, но он обрабатывает так же, как Тиму

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