Я пытаюсь удалить все, кроме даты (дд-мм-гггг) из строки, которую я извлекаю из базы данных в foreach.
Я мог бы просто удалить весь текст ([A-Z] [a-z] и т. д.), Но между текстом тоже есть числа.
$strings = [
'Originele startdatum ',
'Op verzoek van klant de ingangsdatum gelijkgetrokken met alle andere abonnementen zodat er maar 1 factuur wordt verstuurd.'
];
$result[] = [
'AboOpmerking' => str_replace($strings, '', $row['AboOpmerking']),
];
Нетронутые струны выглядят так:
Пример 1:
Originele startdatum 3-10-2017
Пример 2:
Originele startdatum 1-1-2014 Op verzoek van klant de ingangsdatum gelijkgetrokken met alle andere abonnementen zodat er maar 1 factuur wordt verstuurd.
Я нашел это регулярное выражение, но не знаю, как его использовать, потому что оно дает мне пустой массив, когда я печатаю $matches.
^([0]?[1-9]|[1|2][0-9]|[3][0|1])[./-]([0]?[1-9]|[1][0-2])[./-]([0-9]{4}|[0-9]{2})$
Это очень сложное регулярное выражение. Будет ли работать $date = preg_replace("([^0-9-])", "", $stringWithDate);
@DanMiller Нет, потому что, как я сказал в своем вопросе, в тексте могут быть числа после даты, и это, похоже, соответствует всем числам и -
Вы пытаетесь сделать это (?<!\S)\d+-\d+-\d{4}(?!\S)? regex101.com/r/XyECCO/1
@revo Спасибо за это. На данный момент дата не будет иметь другой формат, поэтому принятый ответ меня устраивает. Но я сохраню и эту, спасибо.
Я думаю, вы никоим образом не подтверждаете. Вы просто пытаетесь соответствовать. Таким образом, вам не нужно регулярное выражение-монстр для сопоставления дат. Однако вы можете быть более конкретными, Виктор Стрибьев не был вынужден комментировать предоставленное мной регулярное выражение, но, чтобы отложить его, вы можете немного изменить вышеупомянутое регулярное выражение (?<!\d)\d{1,2}-\d{1,2}-\d{4}(?!\d). Тебе лучше использовать это вместо своего.
Спасибо, пересмотрю, что буду использовать позже.






Вы можете заменить ^ (который соответствует Начало местоположения строки) и $ (который соответствует конец местоположения строки) на \b (границы слов), чтобы сопоставить подстроки даты как целые слова, и использовать preg_match (для извлечения только первого совпадения) или preg_match_all (если их больше одного):
preg_match('~\b(?:0?[1-9]|[12][0-9]|3[01])([./-])(?:0?[1-9]|1[0-2])\1(?:[0-9]{4}|[0-9]{2})\b~', $s, $matches);
См. демонстрация регулярного выражения
Альтернативой границам слов могут быть поисковые пути (?<!\d) и (?!\d) (которые могут быть полезны, если даты могут быть приклеены к буквам или помещены между символами подчеркивания):
preg_match('~(?<!\d)(?:0?[1-9]|[12][0-9]|3[01])([./-])(?:0?[1-9]|1[0-2])\1(?:[0-9]{4}|[0-9]{2})(?!\d)~', $s, $matches);
Оба выглядят хорошо, я думаю, что второй будет более надежным, поэтому я выберу этот. Что именно делает ~?
@KeesSonnema Это разделители регулярных выражений. Они разделяют части регулярного выражения: 1) действие, 2) шаблон и 3) флаги / параметры.
Я знаю, собирался.
@KeesSonnema BTW, revo предлагает более простое регулярное выражение, которое может извлекать подстроки, похожие на даты. (?<!\S)\d+-\d+-\d{4}(?!\S) соответствует 1+ цифрам, -, 1+ цифрам, - и 4 цифрам, если они заключены в пробел (поэтому совпадений внутри знаков препинания или букв нет), и может совпадать со строками 122432345-42343453254564-2456.
Как было предложено, есть альтернатива, в которой вы можете сопоставить дату, например формат \d{1,2}-\d{1,2}-\d{4}, и создать DateTime и, возможно, указать формат, чтобы убедиться, что это действительная дата.
Чтобы заменить только первую дату, вы можете использовать preg_match и preg_replace и указать 1 в качестве четвертого параметра, чтобы выполнить только 1 замену.
$strings = [
'Originele startdatum 3-10-2017',
'Originele startdatum 3-10-2017 3-10-2018 ',
'Originele startdatum 1-1-2014 Op verzoek van klant de ingangsdatum gelijkgetrokken met alle andere abonnementen zodat er maar 1 factuur wordt verstuurd.'
];
$pattern = '/\d{1,2}-\d{1,2}-\d{4}/';
foreach ($strings as $string) {
if (preg_match($pattern, $string, $matches) === 1 && false !== DateTime::createFromFormat('d-m-Y', $matches[0])) {
echo preg_replace($pattern, "", $string, 1) . "<br>";
}
}
Спасибо, пересмотрю, что буду использовать позже.
Вы пытаетесь сопоставить или пытаетесь удалить? Какой должен быть точный вывод?