, Если url
не начинается '/'
, Берут URL текущей страницы, обрубают все мимо последнего '/'; тогда добавьте относительный URL.
Еще, если url
начинается '/'
, Берут URL текущей страницы и обрубают все направо от сингла '/'; тогда добавьте URL.
Еще, если url
запускается с # или?
Берут URL текущей страницы и просто добавляют url
Hope, это работает на Вас
Использование подхода с использованием регулярных выражений:
$regex = <<<'END'
/
(
(?: [\x00-\x7F] # single-byte sequences 0xxxxxxx
| [\xC0-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
| [\xE0-\xEF][\x80-\xBF]{2} # triple-byte sequences 1110xxxx 10xxxxxx * 2
| [\xF0-\xF7][\x80-\xBF]{3} # quadruple-byte sequence 11110xxx 10xxxxxx * 3
){1,100} # ...one or more times
)
| . # anything else
/x
END;
preg_replace($regex, '$1', $text);
Он ищет последовательности UTF-8 и захватывает их в группу 1. Он также сопоставляет отдельные байты, которые не могут быть идентифицированы как часть UTF -8, но не захватывает их. Замена - это то, что было записано в группу 1. Это эффективно удаляет все недопустимые байты.
Можно исправить строку, закодировав недопустимые байты как символы UTF-8. Но если ошибки случайные, это может привести к появлению некоторых странных символов.
$regex = <<<'END'
/
(
(?: [\x00-\x7F] # single-byte sequences 0xxxxxxx
| [\xC0-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
| [\xE0-\xEF][\x80-\xBF]{2} # triple-byte sequences 1110xxxx 10xxxxxx * 2
| [\xF0-\xF7][\x80-\xBF]{3} # quadruple-byte sequence 11110xxx 10xxxxxx * 3
){1,100} # ...one or more times
)
| ( [\x80-\xBF] ) # invalid byte in range 10000000 - 10111111
| ( [\xC0-\xFF] ) # invalid byte in range 11000000 - 11111111
/x
END;
function utf8replacer($captures) {
if ($captures[1] != "") {
// Valid byte sequence. Return unmodified.
return $captures[1];
}
elseif ($captures[2] != "") {
// Invalid byte of the form 10xxxxxx.
// Encode as 11000010 10xxxxxx.
return "\xC2".$captures[2];
}
else {
// Invalid byte of the form 11xxxxxx.
// Encode as 11000011 10xxxxxx.
return "\xC3".chr(ord($captures[3])-64);
}
}
preg_replace_callback($regex, "utf8replacer", $text);
РЕДАКТИРОВАТЬ:
! Empty (x)
будет соответствовать непустым значениям ( «0»
считается пустым) . x! = ""
будет соответствовать непустым значениям, включая "0"
. x! == ""
будет соответствовать чему угодно, кроме ""
. x! = ""
кажется лучшим один, чтобы использовать в этом случае.
Я также немного ускорил матч. Вместо сопоставления каждого символа отдельно, он сопоставляет последовательности допустимых символов UTF-8.
Как насчет iconv:
http://php.net/manual/en/function.iconv.php
Не использовал его внутри самого PHP, но он всегда работал хорошо для меня в командной строке. Вы можете заставить его заменять недопустимые символы.
Итак, правила таковы, что первый октлет UTF-8 имеет высокий бит, установленный в качестве маркера, а затем от 1 до 4 битов, чтобы указать, сколько дополнительных октлетов; тогда для каждого из дополнительных октлетов должны быть установлены два старших бита равными 10.
Псевдо-питон будет выглядеть так:
newstring = ''
cont = 0
for each ch in string:
if cont:
if (ch >> 6) != 2: # high 2 bits are 10
# do whatever, e.g. skip it, or skip whole point, or?
else:
# acceptable continuation of multi-octlet char
newstring += ch
cont -= 1
else:
if (ch >> 7): # high bit set?
c = (ch << 1) # strip the high bit marker
while (c & 1): # while the high bit indicates another octlet
c <<= 1
cont += 1
if cont > 4:
# more than 4 octels not allowed; cope with error
if !cont:
# illegal, do something sensible
newstring += ch # or whatever
if cont:
# last utf-8 was not terminated, cope
Та же самая логика должна быть переведена в php. Однако неясно, какое удаление нужно делать, когда вы получаете искаженный персонаж.
$string = preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_COMPAT, 'UTF-8'));
Если применить utf8_encode()
к уже UTF8-строке, она вернет искаженный UTF8-вывод.
Я сделал функцию, которая решает все эти проблемы. Она называется Encoding::toUTF8()
.
Вам не нужно знать, какая кодировка у ваших строк. Это может быть Latin1 (ISO8859-1), Windows-1252 или UTF8, или строка может иметь их смесь. Encoding::toUTF8()
преобразует все в UTF8.
Я сделал это, потому что один сервис выдавал мне данные в беспорядке, смешивая эти кодировки в одной строке.
Использование:
require_once('Encoding.php');
use \ForceUTF8\Encoding; // It's namespaced now.
$utf8_string = Encoding::toUTF8($mixed_string);
$latin1_string = Encoding::toLatin1($mixed_string);
Я включил еще одну функцию, Encoding::fixUTF8(), которая исправит все строки UTF8, которые выглядят искаженными из-за того, что были закодированы в UTF8 несколько раз.
Usage:
require_once('Encoding.php');
use \ForceUTF8\Encoding; // It's namespaced now.
$utf8_string = Encoding::fixUTF8($garbled_utf8_string);
Examples:
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
will output:
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Download: