Pro regex, преобразовывающий эти невозможные в regex примеры? - PullRequest
1 голос
/ 29 декабря 2011

Пример ввода

vulture (wing)
tabulations: one leg; two legs; flying
father; master; patriarch    
mat (box)
pedistal; blockade; pilar
animal belly (oval)
old style: naval
jackal's belly; jester    slope of hill (arch)
key; visible; enlightened

В принципе, у меня возникли проблемы с некоторыми более сложными командами регулярных выражений.Большая часть кода, который я нахожу с использованием регулярных выражений, очень проста, но я мог бы использовать его во многих местах, если бы мне это удалось.Не могли бы вы взглянуть на то, что я пытаюсь сделать, и посмотреть, сможете ли вы преобразовать что-либо из этого?

  1. Массивизируйте слово или слова между фигурными скобками, "(" и ")".
  2. Массив первых слов после новой строки, заканчивающейся x или четырьмя пробелами, а затем закрывающей скобкой ")", пробелом и открытой скобкой "(" И первыми словами в документе вплоть до пробела иоткрывающая скобка "(".
  3. В любой строке с точкой с запятой массивируйте слова, разделенные точками с запятой. Получите слово или слова после последней точки с запятой, но не получайте слова после разрыва строки или четырех последовательныхпробелы. Слова из строк, начинающиеся со строки «табуляции:», не должны включаться в этот массив, даже если строки, начинающиеся со строки «табуляции:», имеют точку с запятой. Если новая строка заканчивается закрывающей скобкой »,) "стоит перед строкой, содержащей точки с запятой и не начинающейся с" табуляции ", вместо" нет альтернатив "массиву.
  4. Получить слово или слова, следующие зав начале строки, предшествующей разрыву строки, начинающейся со строки «старый стиль:».Если новая строка, оканчивающаяся закрывающей скобкой, ")" ставится перед "tabulations:" - начальная строка, вместо нее добавьте "no old style" в массив.
  5. То же, что 3, за исключением толькостроки, начинающиеся со строки «табуляции:».Если новая строка, оканчивающаяся закрывающей скобкой, «)» ставится перед «табуляцией:» - начальная строка, вместо этого добавьте «нет табуляций» в массив.

Я пытаюсь выяснить,как это сделать через PHP, но я был бы рад, если бы кто-нибудь мог выставить эти запросы на любом языке, особенно php, C ++, javascript или batch.Я также знаю, что все это очень трудно показать, даже для любителя головоломок.Итак, я обещаю 100 бонусных баллов, как только будут получены награды за любой полный ответ.

-Edit-

Первое решение, над которым я работал

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

$input = file_get_contents('explode.txt');
foreach(explode("\n", $input) as $line){
  $words = explode(';', $line); 
  foreach($words as $word){
  echo $word;
  }
}

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

Второе решение, над которым я работаю

Это основано на этой строке кода: preg_match_all('/\;([^;]+)\}/', $myFile, $matches).

Теперь есть рабочее решение для части 1 вопроса, благодаря EPB и fge :

$myFile = file_get_contents('fakexample.txt');
function get_between($startString, $endString, $myFile){
  //Escape start and end strings.
  $startStringSafe = preg_quote($startString, '/');
  $endStringSafe = preg_quote($endString, '/');
  //non-greedy match any character between start and end strings. 
  //s modifier should make it also match newlines.
  preg_match_all("/$startStringSafe(.*?)$endStringSafe/s", $myFile, $matches);
  return $matches;
}
$list = get_between("(", ")", $myFile);
foreach($list[1] as $list){
  echo $list."\n";
}

У меня были некоторые проблемы, которые я не использовалRegEx правильно.Я думаю, что проблема возврата ArrayArray была из-за того, что я не инкапсулировал функцию preg_match_all так, чтобы она возвращала $ match частной функции.Я все еще не уверен.Я также все еще не уверен, стоит ли мне использовать функцию file_get_contents() для чтения файла.

Третья попытка решения

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

function find_between($input,$start,$end) {
  if (strpos($input,$start) === false || strpos($input,$end) === false) {
    return false;
  } else {
    $start_position = strpos($input,$start)+strlen($start);
    $end_position = strpos($input,$end);
    return substr($input,$start_position,$end_position-$start_position);
  }
}

$myFile = file_get_contents('explode.txt');

$output = find_between($myFile,'(',')');

echo $output;

Насколько я могу судить, это сработает.У меня проблема с рекурсией.Я попытался foreach($output as $output){echo $output;}, но это дало мне ошибку.Мне кажется очевидным, что это потому, что я не рекурсировал и не массивизировал.Причина, по которой я остановился на этом пути, заключается в том, что несколько программистов сказали мне, что я обречен на неудачу.Итак, я сейчас вернусь к работе над решением 2.

1 Ответ

1 голос
/ 18 февраля 2014

Это для домашнего задания? Эти инструкции (1-5) не имеют никакого смысла для меня, поскольку у вас есть основания делать какие-либо из них вне академического занятия. Также кажется, что вы новичок не только в регулярных выражениях, но и в PHP в целом. Как отметил @Ховард, мы не будем выполнять вашу работу за вас.

Кроме того, если вам нужна помощь с регулярным выражением, я был бы более чем рад помочь; однако, похоже, вам в этом больше всего не нужна помощь.

Итак, вот что я могу вам предложить относительно вашего вопроса:

3) "В любой строке с точками с запятой массивите слова, разделенные точками с запятой.
Получить слово или слова после последней точки с запятой, но не получить слова после переноса строки или четырех последовательных пробелов. -> Легко: взорваться по новой строке (\ n)

Слова из строк, начинающиеся со строки «табуляции:», не должны включаться в этот массив, даже если строки, начинающиеся со строки «табуляции:», имеют точки с запятой. -> Это немного сложнее. Во-первых, регулярное выражение для точки с запятой, но НЕ двоеточие. Скорее всего, это придется обрабатывать двумя отдельными регулярными выражениями: сначала «табуляции», а если это НЕ найдено, то искать точки с запятой. Если это регулярное выражение выполнено успешно, вы можете взорваться точкой с запятой, и теперь у вас есть все данные для создания всех ваших массивов.

Если новая строка, оканчивающаяся закрывающей скобкой, ")" стоит перед строкой, содержащей точки с запятой и не начинающейся с "табуляций", то вместо "никаких альтернатив" массиву. " по нескольким причинам.; -)

...