Pro regex, преобразовывающий эти невозможные в regex примеры?
Пример ввода
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
По сути, у меня проблемы с некоторыми более сложными командами регулярных выражений. Большая часть кода, который я нахожу, который использует регулярные выражения, очень проста, но я мог бы использовать его во многих местах, если бы мне это удалось. Не могли бы вы взглянуть на то, что я пытаюсь сделать, и посмотреть, сможете ли вы преобразовать что-нибудь из этого?
- Массив слова или слова между фигурными скобками, "(" и ")".
- Массив первых слов после новой строки, заканчивающейся x или четырьмя пробелами, а затем закрывающей скобкой, ")", пробелом и открытой скобкой "(" И первыми словами в документе вплоть до пробела и открывающей скобки "(",
- В любой строке с точкой с запятой массивируйте слова, разделенные точкой с запятой. Получить слово или слова после последней точки с запятой, но не получить слова после переноса строки или четырех последовательных пробелов. Слова из строк, начинающиеся со строки "табуляции:", не должны включаться в этот массив, даже если строки, начинающиеся со строки "табуляции:", содержат точки с запятой. Если новая строка, оканчивающаяся закрывающей скобкой, ")" стоит перед строкой, содержащей точки с запятой и не начинающейся с "табуляций", то вместо "никаких альтернатив" массиву.
- Получить слово или слова, следующие за двоеточием и предшествующие разрыву строки в строке, которая начинается со строки "old style:". Если новая строка, оканчивающаяся закрывающей скобкой, ")" стоит перед "табуляцией:" - начальная строка, вместо этого добавьте "нет старого стиля" в массив.
- То же, что 3, за исключением только строк, начинающихся со строки "табуляции:". Если новая строка, оканчивающаяся закрывающей скобкой, ")" стоит перед "табуляцией:" - начальная строка, вместо этого добавьте "нет табуляций" в массив.
Я пытаюсь выяснить, как это сделать с помощью PHP, но я был бы рад, если бы кто-нибудь мог разместить эти запросы на любом языке, особенно php, C++, javascript или batch. Я также знаю, что все это очень трудно показать, даже для любителя головоломок. Итак, я обещаю 100 бонусных баллов, как только щедрость будет доступна для любого полного ответа.
-Редактировать-
Первое решение, над которым я работал
Итак, первое решение, над которым я работал, - это решение 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-5) не имеют никакого смысла для меня, поскольку у вас есть основания делать какие-либо из них вне академического занятия. Также кажется, что вы новичок не только в регулярных выражениях, но и в PHP в целом. Как отметил @Howard, мы не будем выполнять вашу работу за вас.
Кроме того, если вам нужна помощь с регулярным выражением, я был бы более чем рад помочь; однако не похоже, что это то, что вам нужно помочь больше всего.
Вот что я могу вам предложить по вашему вопросу:
3) "В любой строке с точкой с запятой массива слова, разделенные точкой с запятой.
Получить слово или слова после последней точки с запятой, но не получить слова после переноса строки или четырех последовательных пробелов. -> Легко: взорваться с помощью новой строки (\n)
Слова из строк, начинающиеся со строки "табуляции:", не должны включаться в этот массив, даже если строки, начинающиеся со строки "табуляции:", содержат точки с запятой. -> Это немного сложнее. Во-первых, регулярное выражение для точки с запятой, но НЕ двоеточие. Скорее всего, это придется обрабатывать двумя отдельными регулярными выражениями: сначала "табуляции", а если это НЕ найдено, то ищите точки с запятой. Если это регулярное выражение выполнено успешно, то вы можете взорваться точкой с запятой, и теперь у вас есть все данные для создания всех ваших массивов.
Если новая строка, оканчивающаяся закрывающей скобкой, ")" стоит перед строкой, содержащей точки с запятой и не начинающейся с "табуляций", то вместо "никаких альтернатив" массиву." -> Это я оставляю на ваше усмотрение, чтобы понять по нескольким причинам.;-)