Я только что установил сайт и устаревшую CMS на наш сервер, и я получаю ошибку компиляции POSIX. К счастью, он появляется только в бэкэнде, однако клиент стремится избавиться от него.
Warning: preg_match_all() [function.preg-match-all]: Compilation failed: POSIX collating elements are not supported at offset 32 in /home/kwecars/public_html/webEdition/we/include/we_classes/SEEM/we_SEEM.class.php on line 621
Из того, что я могу сказать, это новая версия PHP, вызывающая проблему. Вот код:
function getAllHrefs($code){ $trenner = "[\040|\n|\t|\r]*"; $pattern = "/<(a".$trenner."[^>]+href".$trenner."[=\"|=\'|=\\\\|=]*".$trenner.") ([^\'\">\040? \\\]*)([^\"\' \040\\\\>]*)(".$trenner."[^>]*)>/sie"; preg_match_all($pattern, $code, $allLinks); // ---- line 621 return $allLinks; }
Как я могу настроить его для работы с новой версией php на этом сервере?
Спасибо заранее, мой вуду просто недостаточно силен;)
[...]
– классы символов , они соответствуют любому символу между скобками, вам не нужно добавлять |
между ними. См. Классы символов .
Таким образом, [abcd]
будет соответствовать a or b or c or d
.
Если вы хотите совместить чередование более одного символа, например red or blue or yellow
, используйте дополнительный шаблон:
"(red|blue|yellow)"
И вы догадались, что [abcd]
эквивалентно (a|b|c|d)
.
Итак, вот что вы можете сделать для своего регулярного выражения:
Для
$trenner = "[\040|\n|\t|\r]*";
Вместо этого напишите:
$trenner = "[\040\n\t\r]*";
И для
"[=\"|=\'|=\\\\|=]"
Вы могли бы сделать
"(=\"|=\'|=\\\\|=)"
Или
"=[\"'\\\\]?"
Кстати, вы можете использовать \s
вместо $trenner
(см. http://www.php.net/manual/en/regexp.reference.escape.php )
Ваше сообщение об ошибке, что «Элементы сопоставления POSIX не поддерживаются», заслуживает некоторого объяснения. В конце концов, что в мире как элемент сопоставления POSIX, и как я могу его избежать?
Короткий ответ заключается в том, что у вас есть знак равенства в квадратных скобках в месте, где его использование зарезервировано для будущего использования, предполагая, что мы когда-либо обходим его реализацию, что не что иное, как определенное. Вы можете пометить это в Perl в командной строке таким образом, что дает гораздо лучшее сообщение об ошибке, чем предоставляет PHP:
% perl -le 'print "abc" =~ /[=foo=]/ || "Fail"' POSIX syntax [= =] is reserved for future extensions in regex; marked by <-- HERE in m/[=foo=] <-- HERE / at -e line 1.
Это короткий ответ; следует более длинный ответ.
Внутри квадратного символьного класса POSIX допускает три различные вложенные скобки, все обозначенные с помощью дополнительного символа внутри скобок в парах:
[:PROPERTY:]
, как в [:alpha:]
. [=ELEMENTS=]
, как в [=eéèëê=]
на английском или французском языках, и [=vw=]
на шведском языке. [.DIGRAPH.]
элементами, предназначенными для подсчета как один символ, имеют дополнительную точку, обрамляющую их: [.DIGRAPH.]
, Как в [.ch.]
Или [.ll.]
За традиционный испанский алфавит. Они иногда называются сокращениями, потому что две или более кодовых точки считаются такой, что эта последовательность представляет собой единую кодовую точку. Perl поддерживает только первый из них, а не второй и третий.
Их все неловко использовать, потому что они должны быть вложены в дополнительный набор скобок, как в [[:punct:]
чтобы означать \pP
или \p{punct}
. Вам нужны дополнительные привязки с параметрами Unicode, когда вы выбираете один из многих, как в [\pL\pN\pM\p{Pc}]
.
Другие два были попыткой поддержки языковых специфических лингвистических элементов в pre-Unicode enviornment в старых 8-битных локалях. Например, для выражения традиционного испанского алфавита, который считает острые акценты над гласными и диаресами над буквой U , как ту же букву, но которая насчитывает тильду над n как совсем другую букву, и которая, кроме того, имеет два орграфа, каждый из которых считается отличную букву, вам нужно написать это в POSIX:
[[=aá=]bc[.ch.]d[=eé=]fgh[=ií=]jkl[.ll.]mnñ[=oó=]pqrst[=uúü=]vwxyz]
Вы можете и иногда сочетать их. Например, в немецких телефонных книгах, где три i- mutated гласных могут быть записаны без диакритики, вставив следующий e :
[a[=ä[.ae.]=]bcdefghijklmno[=ö[.oe.]=]pqrs[=ß[.ss.]=]tu[=ü[.ue.]=]vwxyz]
Таким образом, если $ES
и $DE
являются соответствующими алфавитами этих языков, вы можете сказать что-то вроде
[$ES]{4}
и им соответствуют слова, такие как guía , niño , llave и choco на испанском языке; или на немецком языке
[$DE]{6}
и им соответствуют слова, такие как tschüß или его прописной неакритичный эквивалент, TSCHUESS .
Это неудобно по разным причинам, а не только тем, которые очевидны из двух алфавитов, перечисленных выше. Он не допускает понятия объединения символов, поэтому вам нужно явно добавить их для ненормированного текста, как в [=e\xE9[.e\x{301.]=]
.
Unicode принял другой путь в том, как реализовать лингвистические элементы, подобные этому. К счастью, регулярные выражения Unicode на UTS # 18 не нуждаются в поддержке языковых функций, адаптированных для определенных языков или локалей до уровня 3 . Этого еще никто еще не реализовал.
Обратите внимание, что наличие SS и ß имеет один и тот же регистр, не считающийся положением в локали. Это полный casefold для этой кодовой точки независимо от языкового контекста. Таким образом, те же, когда случай игнорируется. Удивительно, но факт. Учитывая, что ß является кодовой точкой U + 00DF, мы видим, что они одинаковы независимо от языка:
$ perl5.14.0 -E 'say "SS" =~ /^\xDF$/i ? "Pass" : "Fail"' Pass $ perl5.14.0 -E 'say "\xDF" =~ /^SS$/i ? "Pass" : "Fail"' Pass
Хотя привязка локалей к шаблонам все еще находится за пределами нас, была выполнена сортировка, в том числе с поддержкой локали, и вы можете получить доступ к ней с Perl просто отлично.
Однако PHP еще не поддерживает сортировку Unicode.
Ссылки для сортировки Unicode включают: