Назначить шаблон регулярного выражения в качестве ключа к массиву

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

Структура текстового документа:

Subject: sometext

Email: [email protected]

source: www.google.com www.stackoverflow.com www.reddit.com

Итак, у меня есть массив выражений:

$expressions=array(
                'email'=>'(\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}\b)',
                'url'=>'([A-Za-z][A-Za-z0-9+.-]{1,120}:[A-Za-z0-9/](([A-Za-z0-9$_.+!*,;/?:@&~=-])|%[A-Fa-f0-9]{2}){1,333}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*,;/?:@&~=%-]{0,1000}))?)'
               );

Я хочу прокрутить свой текстовый документ и сопоставить адрес электронной почты, затем назначить его в качестве ключа для массива, а затем назначить все URL-адреса, которые следуют, как значения, s вывод для приведенного выше текста будет:

array(
  '[email protected]' => array (
      0 => 'www.google.com',
      1 => 'www.stackoverflow.com',
      2 => 'www.reddit.com'
    )      

person sassy_geekette    schedule 28.07.2010    source источник
comment
Не могли бы вы перефразировать свой вопрос, возможно, показав массивы, которые вы описываете? (т.е. ввод, а также ожидаемый результат)   -  person mvds    schedule 28.07.2010
comment
хорошо, какой смысл выражения в массиве? Всегда ли в нем 2 элемента или их может быть 3 и более?   -  person mvds    schedule 28.07.2010
comment
если у вас есть решение, которое не требует, чтобы они были в массиве, дайте мне знать, я новичок в программировании, и этот проект, над которым я работаю, немного выше моего понимания. Благодарность   -  person sassy_geekette    schedule 28.07.2010
comment
хорошо, так и думал, см. мой ответ.   -  person mvds    schedule 28.07.2010


Ответы (2)


Один из способов сделать это:

$parts = preg_split("/(emailexpr)/",$txt,-1,PREG_SPLIT_DELIM_CAPTURE);

$res = array();

// note: $parts[0] will be everything preceding the first emailexpr match
for ( $i=1; isset($parts[$i]); $i+=2 )
{
    $email = $parts[$i];
    $chunk = $parts[$i+1];
    if ( preg_match_all("/domainexpr/",$chunk,$match) )
    {
        $res[$email] = $match[0];
    }
}

замените emailexpr и domainexpr своей тарабарщиной регулярного выражения.

person mvds    schedule 28.07.2010

Я бы сделал:

$lines = file('input_file', FILE_SKIP_EMPTY_LINES);
$array = array();
foreach($lines as $line) {
  if(preg_match('/^Subject:/', $line) {
    $email = '';
  } elseif(preg_match('/^Email: (.*)$/', $line, $m)) {
    if(preg_match($expressions['email'], $m[1])) {
      $email = $m[1];
    }
  } elseif(preg_match('/^source: (.*)$/', $line, $m) && $email) {
    foreach(explode(' ', $m[1]) as $url) {
      if(preg_match($expressions['url'], $url)) {
        $array[$email][] = $url;
      }
    }
  }
}
person Toto    schedule 28.07.2010
comment
это будет жаловаться на инициализированные элементы массива и неинициализированную переменную, как для вашей обработки, так и для $array - person mvds; 28.07.2010
comment
вам следует заглянуть в preg_match_all, что сделает все чище (он объединит foreach, explode и preg_match, а также предотвратит предупреждение о том, что $array[$email] не установлено. - person mvds; 28.07.2010
comment
@mvds: Вы правы, я пропустил $array = array(); обновлено. Что касается второго пункта, я предпочитаю извлекать URL-адреса раньше, но, конечно, это можно сделать с помощью preg_match_all. - person Toto; 28.07.2010
comment
Ты тоже пропустил if ( !isset($array[$email]) ) $array[$email] = array();... @sassy: посмотри мой ответ - person mvds; 28.07.2010