Master-X
Регистрация
|
Вход
Форум
|
Новости
|
Статьи
Главная
»
Форум
»
Программинг, Скрипты, Софт, Сервисы
»
Тема:
Замена слов в тексте.
Новая тема
Ответить
цитата
31/03/12 в 07:31
Lexikon
Решил для производственной необходимости написать код который бы заменял одни слова на другие. Но тут столкнулся с проблемой.
в скрипте использую такую структуру замены:
<?php
$text = "I'm already here. I've seen that movie several times. I'll deal with this.";
$search = Array("I'm", "I've", "I'll");
$replace = Array("I am", "I have", "I will");
$newtext = str_replace($search, $replace, $text);
echo $newtext;
?>
всё конечно хорошо работает, но тут проблема с регистрами букв, если слово поиска начинается с строчной буквы, а слово замены с заглавной, то замена не произойдет.
Как пример вот это предложение: "Это предложение начинается с большой буквы. Сново же и это предложение начинается с большой буквы.
Допустим нужно заменить "Это предложение" на "Мой текст" в первом предложении замена произойдет, а вот во втором уже нет.
Как быть х.з. единственное пришел к выводу это делать так: Перевести всё в нижний регистр, и слова замены использовать тоже с маленькой буквы, затем разбить текст на массив используя как резделитель точку и уже с помощью ucfirst() изменить каждую строку массива и потом собрать содержимое массива в одну строку.
Может это бред, но пока только такая мысль, ибо знаний и практики еще маловато. Да и в таком варианте есть минусы в том что иногда в тексте встречаются имена, а значит они после такой обрамотки остануться с маленькой буквы. Да и окончание предложения не всегда точкой заканчиваются. Вероятно тут может быть выриант с регулярками, но х.з. буду пока рыться. Попробую еще поиграть с содержимым массива и ucfirst(), думаю тут выход найду.
Если кто то может натолкнуть на правильную мысль, буду благодарен.
цитата
31/03/12 в 08:06
FTS
Используй str_ireplace() вместо str_replace()
Функция str_ireplace() нечувствительна к регистру.
цитата
31/03/12 в 08:56
Lexikon
<?php
$text = "I'm already here. I've seen that movie several times. I'll deal with this, i'm here.";
$search = Array("i'm", "i've", "i'll");
$replace = Array("i am", "i have", "i will");
$newtext = str_ireplace($search, $replace, $text);
echo $newtext;
?>
да замена происходит, но на выходе всё с маленькой буквы (это конечно потому т.к. в $replace всё с маленькой, но сделав запись с большой буквы я получу в тексте всё это с большой буквы и тут станет вопрос опять же - как сделать правильно выглядещее предложение.) даже если я результат загоню в ucfirst($newtext); то на выходе получу только первое предложение с большой буквы.
цитата
31/03/12 в 09:09
FTS
Кстати, I применительно к себе в английском всегда пишется с большой буквы, будь оно в начале, в середине или в конце предложения.
То есть в приведённом тобой примере можно поставить:
$replace = Array("I am", "I have", "I will");
цитата
31/03/12 в 09:14
Lexikon
это как пример
, там будут другие слова.
цитата
31/03/12 в 09:25
samedi
Код:
<?php
$input = "I'M ALREADY HERE. I've seen that movie several times. I'll deal with this, i'm here.";
$replace_list = array(
"i'm" => "i am",
"i've" => "i have",
"i'll" => "i will"
);
foreach ($replace_list as $find => $replace) {
while (($pos = stripos($input, $find)) !== false) {
$word_old = substr($input, $pos, strlen($find));
$mask = strtoupper($word_old) ^ $word_old;
$word_new = strtoupper($replace) | $mask .
str_repeat(substr($mask, -1), strlen($replace) - strlen($word_old));
$input = str_replace($word_old, $word_new, $input);
}
}
echo $input;
Код:
I AM ALREADY HERE. I have seen that movie several times. I will deal with this, i am here.
Стукнись в личку - скажу куда отсылать коньяк.
цитата
31/03/12 в 13:10
kodek
Цитата:
Если кто то может натолкнуть на правильную мысль, буду благодарен.
Хм.. А почему бы просто дважды не проходиться по массиву? Один раз - с заглавными буквами, второй - приведя их же к нижнему регистру (ну и массив замен тоже, соответственно).
цитата
31/03/12 в 13:27
Lexikon
kodek писал:
Хм.. А почему бы просто дважды не проходиться по массиву? Один раз - с заглавными буквами, второй - приведя их же к нижнему регистру (ну и массив замен тоже, соответственно).
Занимался этим вопросом, сразу, но стопрнулся на моменте когда нужно было всё в массив собрать обратно.
Т.е. вот к примеру в этом куске.
$bigReplace = ucfirst($bigReplace)."|";
$bigReplace = explode("|", $bigReplace);
echo $bigReplace;
Читаем массив который написан маленькими буквами, затем его переводим в заглавные, разделяем слова вертикальной чертой и получаем соответственно (I am|I have|I will|
и I'm|I've|I'll|), но в браузере это видно как строку, но пытаясь это записхнуть в массив с помощью explode("|", ....) ничего не вышло, каждое слово было отденьным содержимым массива.
<?php
$text = "I'm already here. I've seen that movie several times. I'll deal with this, i'm here.";
$smallSearch = Array("i'm", "i've", "i'll");
$smallReplace = Array("i am", "i have", "i will");
foreach ($smallReplace as $bigReplace)
{
$bigReplace = ucfirst($bigReplace)."|";
$bigReplace = explode("|", $bigReplace);
echo $bigReplace;
}
echo "<br>";
foreach ($smallSearch as $bigSearch)
{
$bigSearch = ucfirst($bigSearch)."|";
$bigSearch = explode("|", $bigSearch);
echo $bigSearch;
}
$newtext = str_replace($smallSearch, $smallReplace, $text);
//echo ucfirst($newtext);
?>
цитата
31/03/12 в 14:58
kodek
Мне кажется, проблема в том, что ты в цикле foreach работаешь не с самим массивом, а с его отображением. Ты читаешь элементы $smallReplace в переменную $bigReplace, и с ней работаешь, оригинальный массив ведь не меняется при этом. Обращайся к массиву напрямую тогда!
Вот так вот, будут меняться уже сами элменты массива (обрати внимание на символ & перед $bigReplace):
Код:
foreach ($smallReplace as &$bigReplace)
цитата
31/03/12 в 15:04
kodek
Короче - вот так попробуй. Если я правильно понял логику =)
И explode там вообще не нужен!
Код:
<?php
$text = "I'm already here. I've seen that movie several times. I'll deal with this, i'm here.";
$smallSearch = Array("i'm", "i've", "i'll");
$smallReplace = Array("i am", "i have", "i will");
// первый проход - замена строчных
$newtext = str_replace($smallSearch, $smallReplace, $text);
foreach ($smallReplace as &$bigReplace)
{
$bigReplace = ucfirst($bigReplace);
}
foreach ($smallSearch as &$bigSearch)
{
$bigSearch = ucfirst($bigSearch);
}
// второй проход - замена прописных
$newtext = str_replace($smallSearch, $smallReplace, $newtext);
echo $text."<br>".$newtext;
?>
цитата
31/03/12 в 15:24
Lexikon
хммм, сейчас буду разбираться, где закосячил, ибо почти один в один у иеня код получился, но не работает так как нужно.
Спасибо!
цитата
02/04/12 в 09:46
Lexikon
код от samedi отличный, но вот если приходиться менять к примеру
"i'm" => "i'm here"
скрипт уходит в бесконечный цикл
во втором вариианте такого нет, но второй вариант не работает с ТАКИМ ТЕКСТОМ.
Первый вариант если бы не впадал в цикл был бы именно тем что хотел.
Пытался как то заставить не зацикливаться, но в моих случиях получалось что происходила первая замена и всё.
массив
$replace_list = array(
"i'm" => "i am",
"i've" => "i have",
"i'll" => "i will"
);
может содержать до полусотни строк, и сколько замен будет в тексте предсказать невозможно.
Т.е. в таком варианте, получается бесканечный цикл:
<?php
$input = "I'M ALREADY HERE. I've seen that movie several times. I'll deal with this, i'm here.";
$replace_list = array(
"i'm" => "i'm here",
"i've" => "i have",
"i'll" => "i will"
);
foreach ($replace_list as $find => $replace) {
while (($pos = stripos($input, $find)) !== false) {
$word_old = substr($input, $pos, strlen($find));
$mask = strtoupper($word_old) ^ $word_old;
$word_new = strtoupper($replace) | $mask .
str_repeat(substr($mask, -1), strlen($replace) - strlen($word_old));
$input = str_replace($word_old, $word_new, $input);
}
}
echo $input;
?>
цитата
02/04/12 в 10:44
idk2045
вот как вариант.
недостаток что строки поиска надо писать в виде регулярного выражения, но это довольно легко.
каждую строку оборачивай в ``is, i значит нечувствительный к регистру, s поиск по всему тексту, если текст состоит из нескольких строк.
буквы для которых хочешь сохранить регистр оборачивай в скобки, и потом обращайся к ним как $1, $2 и т.п. по порядковому номеру скобок.
Код:
<?
$text = "I'm already here. I've seen that movie several times. i'll deal with this.";
$search = Array("`(I)'m`is", "`(I)'ve`is", "`(I)'ll`is");
$replace = Array("$1 am", "$1 have", "$1 will");
$newtext = preg_replace($search, $replace, $text);
echo $newtext;
цитата
02/04/12 в 13:28
FXIX
Lexikon писал:
Решил для производственной необходимости написать код который бы заменял одни слова на другие. Но тут столкнулся с проблемой.
в скрипте использую такую структуру замены:
<?php
$text = "I'm already here. I've seen that movie several times. I'll deal with this.";
$search = Array("I'm", "I've", "I'll");
$replace = Array("I am", "I have", "I will");
$newtext = str_replace($search, $replace, $text);
echo $newtext;
?>
всё конечно хорошо работает, но тут проблема с регистрами букв, если слово поиска начинается с строчной буквы, а слово замены с заглавной, то замена не произойдет.
ну примерно так.
Цитата:
$data = array(
array("I'm" => "I am"),
array("i'm" => "i am"),
array("I've" => "I have"),
array("i've" => "i have"),
);
foreach ($data as $k => $v) {
preg_replace("~(" . $k . ")~s", $v, $subject);
}
$subject - это текст.
$data - это слова из двух файлов. в одном исходное. в другом замена. ну номер строки должен совпадать.
быстро в один файл 30-50 слов набил. быстро в другой скопипастил. буквы заменил на маленькие.
можно и второй файл генерить. зависит от объемов твоих...
Новая тема
Ответить
Эта страница в полной версии