Модераторы: Aliance, skyboy, MoLeX, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> замена кавычек парными 
V
    Опции темы
Gold Dragon
Дата 29.9.2009, 08:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



помогите разработать алгоритм замены всех кавычек на парные «»

я так понимаю должны соблюдаться следующие условия
- если пробел--кавычка--знак, то «
- если знак--кавычка--пробел, то »
- если знак--кавычка--знак или пробел--кавычка--пробел, то нужно сравнить что идёт до этого.. Это ошибка, но такое возможно
- исключить обработку кавычек в тегах


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
sTa1kEr
Дата 29.9.2009, 09:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 5
Всего: 146



Код

function quoteReplace($m) {
    // Если $m - не массив, значит - это строка которую нужно обработать
    if (!is_array($m)) {
        // Замена с обратным вызовом этой же функции
        return preg_replace_callback('/(?:(<[^>]+>)|(["\'](?=\w))|(["\']))/', __FUNCTION__, $m);

    // Если массив, значит это callback вызов функции preg_replace_callback()
    // т.к. она всегда передает массив подшаблонов в качестве первого параметра
    } else {
        // Какой именно подшаблон совпал можно узнать по их количеству.
        // По умолчанию возвращаем текст нетронутым
        switch (count($m)) {
            case 3: return '«';
            case 4: return '»';
            default: return $m[0];
        }   
    }
}

var_dump(quoteReplace('text "quoted \'quoted\' text" <a href="link.com">')); // string(51) "text «quoted «quoted» text» <a href="link.com">"


Это сообщение отредактировал(а) sTa1kEr - 29.9.2009, 10:38
PM MAIL   Вверх
Gold Dragon
Дата 29.9.2009, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



отличная функция!!! Есть маленький нюанс.. не обрабатываются кавычки которые находятся между пробелами


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
sTa1kEr
Дата 29.9.2009, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 5
Всего: 146



Цитата(Gold Dragon @  29.9.2009,  11:21 Найти цитируемый пост)
Есть маленький нюанс.. не обрабатываются кавычки которые находятся между пробелами 

Действительно. К тому же заметил, что можно было еще проще шаблон записать. Подправил пост.

Однако, здесь все равно не учитывается пункт
Цитата(Gold Dragon @  29.9.2009,  09:21 Найти цитируемый пост)
- если знак--кавычка--знак или пробел--кавычка--пробел, то нужно сравнить что идёт до этого.. Это ошибка, но такое возможно

т.к. при этом пришлось бы сильно усложнить алгоритм. И потом возможна неоднозначная ситуация, когда невозможно правильно определить как должны идти кавычки, пример:
Код

Text " begin quote 1 " qoute 2 " end quote 1 " text.

Здесь можно было бы расставить кавычки так:
Код

Text « begin quote 1 « qoute 2 » end quote 1 » text.

и так
Код

Text « begin quote 1 » qoute 2 « end quote 1 » text.

По этому, этот пункт может внести еще большую путаницу с кавычками.

Добавлено @ 10:47
Доработал с учетом (частично) третьего пункта:
Код

function quoteReplace($m) {
    // Индикация, что кавычка открыта
    static $open;

    // Если $m - не массив, значит - это строка которую нужно обработать
    if (!is_array($m)) {
        $open = false;

        // Замена с обратным вызовом этой же функции
        return preg_replace_callback('/(?:(<[^>]+>)|(["\'](?=\w))|((?<=\w)["\'])|(["\']))/u', __FUNCTION__, $m);

    // Если массив, значит это callback вызов функции preg_replace_callback()
    // т.к. она всегда передает массив подшаблонов в качестве первого параметра
    } else {

        // Какой именно подшаблон совпал можно узнать по их количеству.
        // По умолчанию возвращаем текст нетронутым
        switch (count($m)) {
            case 3: $open = true; return '«';
            case 4: $open = false; return '»';
            case 5: $open = !$open; return $open ? '«' : '»';
            default: return $m[0];
        }
    }
}

var_dump(quoteReplace('Text " begin quote 1 " qoute 2 " end quote 1 " text.')); // Text « begin quote 1 » qoute 2 « end quote 1 » text.



Это сообщение отредактировал(а) sTa1kEr - 29.9.2009, 10:52
PM MAIL   Вверх
Gold Dragon
Дата 29.9.2009, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



в общем погонял, всё работает smile 
Не могу пока найти комбинацию, которая бы создала ошибку smile Значит будем считать что вопрос решён


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
sTa1kEr
Дата 29.9.2009, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 5
Всего: 146



Можно еще такой вариант (с учетом различных кавычек)
Код

function quoteReplace($m) {
    // Индикация, что кавычка открыта
    static $open;

    // Если $m - не массив, значит - это строка которую нужно обработать
    if (!is_array($m)) {
        $open = array("'" => false, '"' => false);

        // Замена с обратным вызовом этой же функции
        return preg_replace_callback('/(?:(<\w[^>]*>)|("|\'))/u', __FUNCTION__, $m);

    // Если массив, значит это callback вызов функции preg_replace_callback()
    // т.к. она всегда передает массив подшаблонов в качестве первого параметра
    } else {

        // Какой именно подшаблон совпал можно узнать по их количеству.
        // По умолчанию возвращаем текст нетронутым
        if (count($m) > 2) {
            // Одна из кавычек
            return ($open[$m[2]] = !$open[$m[2]]) ? '«' : '»';
        } else {
            // Это тэг
            return $m[0];
        }
    }
}

var_dump(quoteReplace('Text " begin quote 1 \' quote in quote \' end quote 1 " text.')); // string(63) "Text « begin quote 1 « quote in quote » end quote 1 » text."



Это сообщение отредактировал(а) sTa1kEr - 29.9.2009, 11:13
PM MAIL   Вверх
Gold Dragon
Дата 29.9.2009, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



sTa1kEr, можешь описать что это делает?
Код

preg_replace_callback('/(?:(<\w[^>]*>)|("|\'))/u', __FUNCTION__, $m);


Добавлено через 4 минуты и 51 секунду
sTa1kEr, по-моему стало не очень.. Вот результат первой и второй

Код

var_dump(quoteReplace1('text " dd "dd" '));


на выходе 
string(15) "text « dd «dd» " 
string(15) "text « dd »dd« "

первая грамотнее

Это сообщение отредактировал(а) Gold Dragon - 29.9.2009, 11:21


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
sTa1kEr
Дата 29.9.2009, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 5
Всего: 146



Цитата(Gold Dragon @  29.9.2009,  12:20 Найти цитируемый пост)
sTa1kEr, можешь описать что это делает?

Замена по регулярному выражению, с вызовом callback-функции. Однако в качестве самой callback-функции здесь выступает та-же функция в которой вызывается этот метод (магическая константа __FUNCTION__ содержит имя текущей функции), т.е. preg_replace_callback вызывает рекурсивно эту-же функцию в которой он находится, но уже с массивом в качестве параметра.

Добавлено через 13 минут и 46 секунд
Цитата(Gold Dragon @  29.9.2009,  12:20 Найти цитируемый пост)
sTa1kEr, по-моему стало не очень.. Вот результат первой и второй

Ну это уже дело вкуса smile Если по правилам русского языка первый вариант и правильный, то по логике оба варианта не правильные  т.к. кавычек не четное число.
PM MAIL   Вверх
Gold Dragon
Дата 29.9.2009, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



Ну вообще-то нечётное число допускается.. например ОАО «Энская компания «Рога и Копыта»


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
sTa1kEr
Дата 29.9.2009, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 5
Всего: 146



Я и говорю, допускается в русском языке, но не допускается в программировании.
PM MAIL   Вверх
Gold Dragon
Дата 29.9.2009, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



ну мне для русского языка smile Ещё раз спасибо...


зы
можно пометить, первый вариант для русского языка, второй для программеров  smile

Добавлено через 3 минуты и 6 секунд
sTa1kEr, ещё в догонку... расскажи условия регулярки.. знаний не хватает понять smile


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Тексты | Следующая тема »


 




[ Время генерации скрипта: 0.0602 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.