PHP - найти/заменить текст в файлах RTF/txt

У меня возникла проблема с поиском определенного текста и заменой его альтернативным текстом. Я тестирую свой код ниже только с файлами .rtf и .txt. Я также гарантирую, что файлы доступны для записи изнутри моего сервера.

Это случайная ситуация, и мне любопытно, неправильный ли мой код, или это просто странность открытия файлов и манипулирования ими.

<?php

$filelocation = '/tmp/demo.txt';
$firstname = 'John';
$lastname = 'Smith';

$output = file_get_contents($filelocation);
$output = str_replace('[[FIRSTNAME]]', $firstname, $output);
$output = str_replace('[[LASTNAME]]', $lastname, $output);
$output = str_replace('[[TODAY]]', date('F j, Y'), $output);

// rewrite file
file_put_contents($filelocation, $output);

?>

Итак, внутри файла demo.txt у меня есть примерно полная страница текста с [[ИМЯ]], [[ФАМИЛИЯ]] и [[СЕГОДНЯ]].

Это удар и промах с поиском / заменой. Пока что [[TODAY]] всегда заменяется правильно, а имена — нет.

У кого-нибудь была такая же проблема?

(кстати, я проверил журналы ошибок, и до сих пор не возвращалось предупреждение/ошибка PHP ни при открытии файла, ни при его записи)


person coffeemonitor    schedule 20.03.2013    source источник
comment
Вы можете поместить немного текста в demo.txt, чтобы мы могли понять, что не так   -  person safarov    schedule 20.03.2013
comment
Хорошая мысль, попробую....   -  person coffeemonitor    schedule 20.03.2013
comment
Странно - попробовал ваш код с простым текстовым файлом, и он работает именно так, как ожидалось. Не знаю, что происходит с вашими вещами. Выложить демонстрационный файл?   -  person Polsonby    schedule 20.03.2013
comment
Позвольте мне видеть, если я получил это прямо. Вы хотите заменить [[FIRSTNAME]] на John и [[LASTNAME]] на Smith?   -  person Funk Forty Niner    schedule 20.03.2013
comment
Точно, это сценарий поиска и замены.   -  person coffeemonitor    schedule 21.03.2013
comment
Другой вопрос. Это именно строка [[FIRSTNAME]] или [[John]], [[Robert]] и т. д. в качестве имен? Я спрашиваю об этом, потому что тесты, которые я сделал, играя с ним, оказались положительными.   -  person Funk Forty Niner    schedule 21.03.2013


Ответы (2)


Трудно сказать наверняка, не видя содержимого demo.txt. Мое первое предположение заключается в том, что это может быть проблема с использованием скобок для ваших указателей. Я бы попробовал изменить на что-то, что не используется RTF, например, знак процента или звездочку. пример: %%FIRSTNAME%%, **FIRSTNAME** (конечно, предполагается, что вы контролируете содержимое demo.txt.)

person Jordan    schedule 20.03.2013
comment
Похоже, это действительно проблема .rtf. Я проверил это с помощью .txt, и там все работает нормально. Возможно, есть странные невидимые добавки форматирования, созданные Microsoft Word. - person coffeemonitor; 21.03.2013
comment
Да, RTF добавляет все типы символов форматирования. Пожалуйста, проголосуйте или отметьте как ответ, если мой ответ был полезен. Спасибо! - person Jordan; 21.03.2013
comment
ты прав. Мне нужно было проголосовать. Я использовал вашу идею, чтобы попробовать разные параметры маркировки Pre/Post. Кроме того, я удалил все форматирование из .rtf и, похоже, это было решением. Ура для Rich Text, своего рода. - person coffeemonitor; 21.03.2013
comment
Я сталкивался с этим несколько раз. Рад, что смог помочь ;) - person Jordan; 21.03.2013

У меня тоже была эта проблема. Похоже, что Microsoft Word вставляет коды форматирования в теги. Я сделал сообщение в блоге о том, как обойти это в моем техническом блоге.

http://tech.humlesite.eu/2017/01/13/using-regular-expression-to-merge-database-content-into-rich-text-format-template-documents/

Пример PHP показан здесь:

<?php 

$file = file_get_contents('mergedoc.rtf');

// To temporary get rid of the escape characters...
$mergetext = str_replace("\\", "€€", $file); 

// New seven part regex with default value detection
$regex2 = '/<<((?:€€[a-z0-9]*|\}|\{|\s)*)([a-z0-9.\-\+_æøåÆØÅA-Z]*)((?:€€[a-z0-9]*|\}|\{|\s)*)([a-z0-9.\-\+_æøåÆØÅA-Z]*)((?:€€[a-z0-9]*|\}|\{|\s)*)(?:\s*:(.*?)\s*)?((?:€€[a-z0-9]*|\}|\{|\s)*)>>/';

// Find all the matches in it....
preg_match_all($regex2,$mergetext, $out, PREG_SET_ORDER);

// Lets see the result
var_dump($out); 

foreach ($out as $match) {
    $whole_tag = $match[0]; // The part we actually replace. 
    $start = $match[1]; // The start formatting that has been injected in our tag, if any
    $tag = $match[2]; // The tag word itself. 
    if (($match[4].$match[6]) != "") { //some sec-part tag or default value?
        $end = $match[5]; // The end formatting that might be inserted. 
        if ($end == "") {
            $end = $match[7]; // No end in 5, we try 7. 
        }
    } else {
        $end = $match[3]; // No second tag or default value, we find end in match-3 
    }

    $secPartTag = $match[4]; // Do we have inserted some formatting inside the tag word too ? 
    if ($secPartTag != "") {
        $tag .= $secPartTag; // Put it together with the tag word. 
    }
    $default_value = $match[6]; 

    // Simple selection of what we do with the tag. 
    switch ($tag) {
        case 'COMPANY_NAME': 
            $txt = "MY MERGE COMPANY EXAMPLE LTD"; 
            break; 
        case 'SOMEOTHERTAG':
            $txt = "SOME OTHER TEXT XX"; 
            break; 
        case 'THISHASDEFAULT':
            $txt = ""; 
            break; 

        default:
            $txt = "NOTAG"; 
    }
    if ($txt == "") {
        $txt = $default_value; 
    }
    // Create RTF Line breaks in text, if any. 
    $txt = str_replace(chr(10), chr(10)."\\line", $txt); 
    // Do the replace in the file. 
    $mergetext = str_replace($whole_tag, $start.$txt.$end, $mergetext); 
}
// Put back the escape characters. 
$file = str_replace("€€", "\\", $mergetext);
// Save to file. Extention .doc makes it open in Word by default. 
file_put_contents("ResultDoc.doc", $file); 

?>
person olekeh    schedule 21.01.2017