PHP preg_match / undefined offset - PullRequest
       25

PHP preg_match / undefined offset

1 голос
/ 07 марта 2012

У меня есть скрипт редактирования, который извлекает события календаря и позволяет пользователю редактировать эти события.

Есть 3 типа событий; однократное, ежедневное и еженедельное.

Сценарий редактирования обрабатывает все 3 типа (где формат данных немного отличается для каждого).

Что касается двух типов повторяющихся событий, я не могу сказать, какой из них обрабатывается, пока я не использую preg_match. У меня есть 2 функции preg_match, первая для ежедневных повторяющихся событий, а вторая для еженедельных повторяющихся событий.

Мой код сначала передает строку, содержащую информацию о событии, в ежедневную функцию preg_match. Если переменные назначены, то проблем нет.

Если переменные не были назначены, я передаю ту же строку в еженедельную функцию preg_match. Здесь я получаю следующую ошибку:

Notice: Undefined offset:

Сейчас я покажу свой код.

Для начала, 2 типа строки:

(Daily Recurring Event)
DTSTART;VALUE=DATE:20120306 DTEND;VALUE=DATE:20120307 RRULE:FREQ=DAILY;INTERVAL=3;UNTIL=20120331 

(Weekly Recurring Event)
DTSTART;VALUE=DATE:20120201 DTEND;VALUE=DATE:20120201 RRULE:FREQ=WEEKLY;BYDAY=Tu,Fr;UNTIL=20120331

Вышеуказанные строки хранятся в переменной $ eventtype

Код для обработки этого:

recurrence_info_day($eventtype);
$recurrence_type = "daily";
if ($d = false){
    recurrence_info_weekly($eventtype);
    $recurrence_type = "weekly";
}

function recurrence_info_day($eventtype){
    global $eventstart, $eventend, $eventfrequency, $eventinterval, $eventuntil, $formstartdate, $formenddate, $xyz;
    $s = $eventtype;    
    preg_match(
      '/^DTSTART;VALUE=DATE:(\d+)\s+DTEND;VALUE=DATE:(\d+)\s+RRULE:FREQ=(\w+);INTERVAL=(\d+);UNTIL=(\d+)/',
      $s,
      $recinfod
    );
    $eventstart = $recinfod[1];
    $eventend = $recinfod[2];
    $eventfrequency = $recinfod[3];
    $eventinterval = $recinfod[4];
    $eventuntil = $recinfod[5];

    $formstartdate = substr($eventstart,4,2)."/".substr($eventstart, 6)."/".substr($eventstart,0,4);
    $formenddate = substr($eventuntil,4,2)."/".substr($eventuntil, 6)."/".substr($eventuntil,0,4);

    $d = true;
    if (!$eventstart){
         $d = false;
    }
}

//Weekly recurring events
function recurrence_info_weekly($eventtype){
    global $eventstart, $eventend, $eventfrequency, $eventdays, $eventuntil, $formstartdate, $formenddate;
    $s = $eventtype;
    preg_match(
        '/^DTSTART;VALUE=DATE:(\d+)\s+DTEND;VALUE=DATE:(\d+)\sRRULE:FREQ=(\w+);BYDAY= (\d+);UNTIL=(\d+)/',
        $s,
        $recinfow
    );
    $eventstart = $recinfow[1];
    $eventend = $recinfow[2];
    $eventfrequency = $recinfow[3];
    $eventdays = $recinfow[4];
    $eventuntil = $recinfow[5];

    $formstartdate = substr($eventstart,4,2)."/".substr($eventstart, 6)."/".substr($eventstart,0,4);
    $formenddate = substr($eventuntil,4,2)."/".substr($eventuntil, 6)."/".substr($eventuntil,0,4);
}

Когда у меня ежедневное повторяющееся событие, этот скрипт работает как надо.

Насколько я могу судить, проблема в функции preg_match для еженедельной строки - recurring_info_weekly () Я получаю неопределенные ошибки смещения, когда вызываю эту функцию в одиночку или как в приведенном выше коде. Функция recurring_info_day () работает. Это просто функция недели, которая выдает ошибку.

Любая помощь приветствуется, спасибо:)

Ответы [ 2 ]

2 голосов
/ 07 марта 2012

Я вижу проблему в вашем втором паттерне. Вы проверяете цифры после BYDAY, но в вашем примере в этой позиции есть буквенные символы. Это вызовет только 4 совпадения во втором шаблоне и неопределенное смещение при попытке доступа к [5].

DTSTART;VALUE=DATE:20120201 DTEND;VALUE=DATE:20120201 RRULE:FREQ=WEEKLY;BYDAY=Tu,Fr;UNTIL=20120331

/^DTSTART;VALUE=DATE:(\d+)\s+DTEND;VALUE=DATE:(\d+)\sRRULE:FREQ=(\w+);BYDAY=(\d+);UNTIL=(\d+)/
//-------------------------------------------------------------------------^^^^^^^

Вместо этого вы можете попробовать заменить его на [A-za-z,], чтобы соответствовать буквам и запятой.

/^DTSTART;VALUE=DATE:(\d+)\s+DTEND;VALUE=DATE:(\d+)\sRRULE:FREQ=(\w+);BYDAY=([A-za-z,]+);UNTIL=(\d+)/
//---------------------------------------------------------------------------^^^^^^^
1 голос
/ 07 марта 2012

BYDAY=(\d+) в еженедельном регулярном выражении неверно, \ d означает цифры, что означает, что он не будет совпадать в строке «Mo, Fr». Try BYDAY=([\w,]+) вместо.

...