2012-01-08 2 views
44

Я получаю странные символы при натяжении данных с веб-сайта:Удалить не-ASCII символы из строки

 

Как я могу удалить все, что не является не-ASCII символов расширенного?

+0

Что вы имеете в виду, когда вы говорите, не-ASCII, ' Â' является символом ascii (# 194) –

+0

oh. ну, я имею в виду такие вещи, как буквы и символы, такие как $ (# * @. Я не знаю, как объяснить это, кроме того, что мне нужны только символы, которые вы могли бы ввести на клавиатуре. – LordZardeck

+0

Вы имеете в виду не буквенно-цифровые ? – j08691

ответ

66

Лучше всего заменить замену регулярного выражения. Использование $str в качестве примера строки и сопоставления его с помощью :print:, который является POSIX Character Class:

$str = 'aAÂ'; 
$str = preg_replace('/[[:^print:]]/', '', $str); // should be aA 

Что :print: делает искать для всех печатаемых символов. Обратный, :^print:, ищет все непечатаемые символы. Любые символы, которые не являются частью текущего набора символов, будут удалены.

Примечание: Перед использованием этого метода вы должны убедиться, что ваш текущий набор символов - ASCII. Классы символов POSIX поддерживают как ASCII, так и Unicode и будут соответствовать только в соответствии с текущим набором символов. Начиная с PHP 5.6, кодировка по умолчанию - UTF-8.

+4

Это решение не работает для меня. :( Я получение aA. php 5.3.0. (windows) – DamirR

+0

это решение зависит от локализации библиотеки regex perl ... в частности, это кажется, требует сломанной bersion – Jasen

+0

@ Jasen Они известны как [классы символов POSIX] (http://www.regular-expressions.info/posixbrackets.html). Они работают с любой версией, но требуют, чтобы ASCII был выбранным набором символов в PHP, поскольку классы символов также поддерживают Unicode полностью. Я обновил свой ответ соответственно. –

32

Вы хотите только ASCII printable characters?

использовать это:

<?php 
header('Content-Type: text/html; charset=UTF-8'); 
$str = "abqwrešđčžsff"; 
$res = preg_replace('/[^\x20-\x7E]/','', $str); 
echo "($str)($res)"; 

Или еще лучше, преобразовать ваш вклад в utf8 и использовать phputf8 lib переводить «не нормальные» символы в их ASCII представлении:

require_once('libs/utf8/utf8.php'); 
require_once('libs/utf8/utils/bad.php'); 
require_once('libs/utf8/utils/validation.php'); 
require_once('libs/utf8_to_ascii/utf8_to_ascii.php'); 

if(!utf8_is_valid($str)) 
{ 
    $str=utf8_bad_strip($str); 
} 

$str = utf8_to_ascii($str, ''); 
+2

Я также хотел сохранить символ табуляции, поэтому я использовал это регулярное выражение: [^ \ x00- \ x7E] –

1

Я просто должен был добавить заголовок

header('Content-Type: text/html; charset=UTF-8'); 
+1

, который исправит случай, когда UTF8 интерпретируется как WIN-1252, который является кодировка по умолчанию для HTML, однако она не удалит символы из строки. – Jasen

15

У нас есть веб-приложение, которое имело для передачи данных в унаследованную систему, которая может обрабатывать только первые 128 символов набора символов ASCII.

Решение, которое мы должны были использовать, было «перевести» как можно больше символов в эквивалентные ASCII эквиваленты, но оставить все, что невозможно перевести в одиночку.

Обычно я хотел бы сделать что-то вроде этого:

<?php 
// transliterate 
if (function_exists('iconv')) { 
    $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); 
    } 
?> 

... но это заменяет все, что не может быть переведен на вопросительный знак (?).

Итак, мы закончили делать следующее. Проверьте в конце этой функции выражение (закомментированное) php regex, которое просто вычеркивает символы, отличные от ASCII.

<?php 
public function cleanNonAsciiCharactersInString($orig_text) { 

    $text = $orig_text; 

    // Single letters 
    $text = preg_replace("/[∂άαáàâãªä]/u",  "a", $text); 
    $text = preg_replace("/[∆лДΛдАÁÀÂÃÄ]/u",  "A", $text); 
    $text = preg_replace("/[ЂЪЬБъь]/u",   "b", $text); 
    $text = preg_replace("/[βвВ]/u",   "B", $text); 
    $text = preg_replace("/[çς©с]/u",   "c", $text); 
    $text = preg_replace("/[ÇС]/u",    "C", $text);   
    $text = preg_replace("/[δ]/u",    "d", $text); 
    $text = preg_replace("/[éèêëέëèεе℮ёєэЭ]/u", "e", $text); 
    $text = preg_replace("/[ÉÈÊË€ξЄ€Е∑]/u",  "E", $text); 
    $text = preg_replace("/[₣]/u",    "F", $text); 
    $text = preg_replace("/[НнЊњ]/u",   "H", $text); 
    $text = preg_replace("/[ђћЋ]/u",   "h", $text); 
    $text = preg_replace("/[ÍÌÎÏ]/u",   "I", $text); 
    $text = preg_replace("/[íìîïιίϊі]/u",  "i", $text); 
    $text = preg_replace("/[Јј]/u",    "j", $text); 
    $text = preg_replace("/[ΚЌК]/u",   'K', $text); 
    $text = preg_replace("/[ќк]/u",    'k', $text); 
    $text = preg_replace("/[ℓ∟]/u",    'l', $text); 
    $text = preg_replace("/[Мм]/u",    "M", $text); 
    $text = preg_replace("/[ñηήηπⁿ]/u",   "n", $text); 
    $text = preg_replace("/[Ñ∏пПИЙийΝЛ]/u",  "N", $text); 
    $text = preg_replace("/[óòôõºöοФσόо]/u", "o", $text); 
    $text = preg_replace("/[ÓÒÔÕÖθΩθОΩ]/u",  "O", $text); 
    $text = preg_replace("/[ρφрРф]/u",   "p", $text); 
    $text = preg_replace("/[®яЯ]/u",    "R", $text); 
    $text = preg_replace("/[ГЃгѓ]/u",    "r", $text); 
    $text = preg_replace("/[Ѕ]/u",    "S", $text); 
    $text = preg_replace("/[ѕ]/u",    "s", $text); 
    $text = preg_replace("/[Тт]/u",    "T", $text); 
    $text = preg_replace("/[τ†‡]/u",    "t", $text); 
    $text = preg_replace("/[úùûüџμΰµυϋύ]/u",  "u", $text); 
    $text = preg_replace("/[√]/u",    "v", $text); 
    $text = preg_replace("/[ÚÙÛÜЏЦц]/u",   "U", $text); 
    $text = preg_replace("/[Ψψωώẅẃẁщш]/u",  "w", $text); 
    $text = preg_replace("/[ẀẄẂШЩ]/u",   "W", $text); 
    $text = preg_replace("/[ΧχЖХж]/u",   "x", $text); 
    $text = preg_replace("/[ỲΫ¥]/u",   "Y", $text); 
    $text = preg_replace("/[ỳγўЎУуч]/u",  "y", $text); 
    $text = preg_replace("/[ζ]/u",    "Z", $text); 

    // Punctuation 
    $text = preg_replace("/[‚‚]/u", ",", $text);   
    $text = preg_replace("/[`‛′’‘]/u", "'", $text); 
    $text = preg_replace("/[″“”«»„]/u", '"', $text); 
    $text = preg_replace("/[—–―−–‾⌐─↔→←]/u", '-', $text); 
    $text = preg_replace("/[ ]/u", ' ', $text); 

    $text = str_replace("…", "...", $text); 
    $text = str_replace("≠", "!=", $text); 
    $text = str_replace("≤", "<=", $text); 
    $text = str_replace("≥", ">=", $text); 
    $text = preg_replace("/[‗≈≡]/u", "=", $text); 


    // Exciting combinations  
    $text = str_replace("ыЫ", "bl", $text); 
    $text = str_replace("℅", "c/o", $text); 
    $text = str_replace("₧", "Pts", $text); 
    $text = str_replace("™", "tm", $text); 
    $text = str_replace("№", "No", $text);   
    $text = str_replace("Ч", "4", $text);     
    $text = str_replace("‰", "%", $text); 
    $text = preg_replace("/[∙•]/u", "*", $text); 
    $text = str_replace("‹", "<", $text); 
    $text = str_replace("›", ">", $text); 
    $text = str_replace("‼", "!!", $text); 
    $text = str_replace("⁄", "/", $text); 
    $text = str_replace("∕", "/", $text); 
    $text = str_replace("⅞", "7/8", $text); 
    $text = str_replace("⅝", "5/8", $text); 
    $text = str_replace("⅜", "3/8", $text); 
    $text = str_replace("⅛", "1/8", $text);   
    $text = preg_replace("/[‰]/u", "%", $text); 
    $text = preg_replace("/[Љљ]/u", "Ab", $text); 
    $text = preg_replace("/[Юю]/u", "IO", $text); 
    $text = preg_replace("/[fifl]/u", "fi", $text); 
    $text = preg_replace("/[зЗ]/u", "3", $text); 
    $text = str_replace("£", "(pounds)", $text); 
    $text = str_replace("₤", "(lira)", $text); 
    $text = preg_replace("/[‰]/u", "%", $text); 
    $text = preg_replace("/[↨↕↓↑│]/u", "|", $text); 
    $text = preg_replace("/[∞∩∫⌂⌠⌡]/u", "", $text); 


    //2) Translation CP1252. 
    $trans = get_html_translation_table(HTML_ENTITIES); 
    $trans['f'] = '&fnof;'; // Latin Small Letter F With Hook 
    $trans['-'] = array(
     '&hellip;',  // Horizontal Ellipsis 
     '&tilde;',  // Small Tilde 
     '&ndash;'  // Dash 
     ); 
    $trans["+"] = '&dagger;'; // Dagger 
    $trans['#'] = '&Dagger;'; // Double Dagger   
    $trans['M'] = '&permil;'; // Per Mille Sign 
    $trans['S'] = '&Scaron;'; // Latin Capital Letter S With Caron   
    $trans['OE'] = '&OElig;'; // Latin Capital Ligature OE 
    $trans["'"] = array(
     '&lsquo;', // Left Single Quotation Mark 
     '&rsquo;', // Right Single Quotation Mark 
     '&rsaquo;', // Single Right-Pointing Angle Quotation Mark 
     '&sbquo;', // Single Low-9 Quotation Mark 
     '&circ;', // Modifier Letter Circumflex Accent 
     '&lsaquo;' // Single Left-Pointing Angle Quotation Mark 
     ); 

    $trans['"'] = array(
     '&ldquo;', // Left Double Quotation Mark 
     '&rdquo;', // Right Double Quotation Mark 
     '&bdquo;', // Double Low-9 Quotation Mark 
     ); 

    $trans['*'] = '&bull;'; // Bullet 
    $trans['n'] = '&ndash;'; // En Dash 
    $trans['m'] = '&mdash;'; // Em Dash   
    $trans['tm'] = '&trade;'; // Trade Mark Sign 
    $trans['s'] = '&scaron;'; // Latin Small Letter S With Caron 
    $trans['oe'] = '&oelig;'; // Latin Small Ligature OE 
    $trans['Y'] = '&Yuml;'; // Latin Capital Letter Y With Diaeresis 
    $trans['euro'] = '&euro;'; // euro currency symbol 
    ksort($trans); 

    foreach ($trans as $k => $v) { 
     $text = str_replace($v, $k, $text); 
    } 

    // 3) remove <p>, <br/> ... 
    $text = strip_tags($text); 

    // 4) &amp; => & &quot; => ' 
    $text = html_entity_decode($text); 


    // transliterate 
    // if (function_exists('iconv')) { 
    // $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); 
    // } 

    // remove non ascii characters 
    // $text = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $text);  

    return $text; 
} 

?> 
+0

Согласно http://php.net/manual/en/function.iconv.php#74101, это должно быть проблемой только в том случае, если вы не выбрали правильную локаль (кроме C или POSIX). – MauganRa

+0

Вы когда-нибудь сравнивали это ? –

+0

Хорошая работа. Спасибо. – Duque

0

Это должно быть довольно прямо вперед, и нет необходимости в Iconv функции:

// Remove all characters that are not the separator, a-z, 0-9, or whitespace 
$string = preg_replace('![^'.preg_quote('-').'a-z0-_9\s]+!', '', strtolower($string)); 
// Replace all separator characters and whitespace by a single separator 
$string = preg_replace('!['.preg_quote('-').'\s]+!u', '-', $string); 
0

Я думаю, что лучший способ сделать что-то вроде этого с помощью команды ORD(). Таким образом, вы сможете хранить символы, написанные на любом языке. Просто не забудьте сначала проверить результаты вашего текста. Это не будет работать в Юникоде.

$name="βγδεζηΘ[email protected]#$%^&";  
//this function will clear all non greek and english characters on greek-iso charset   
function replace_characters($string)  
{  
    $str_length=strlen($string);  
    for ($x=0;$x<$str_length;$x++)  
     {  
      $character=$string[$x];  
      if ((ord($character)>64 && ord($character)<91) || (ord($character)>96 && ord($character)<123) || (ord($character)>192 && ord($character)<210) || (ord($character)>210 && ord($character)<218) || (ord($character)>219 && ord($character)<250) || ord($character)==252 || ord($character)==254)  
      {  
       $new_string=$new_string.$character;  
      }  
     }  
     return $new_string;  
}  
//end function  

$name=replace_characters($name);  

echo $name;  
+0

Тяжелый, но тщеславный ... Мне это нравится. –

+0

Вы повторяете ord() для одного и того же символа снова и снова только для разных сравнений (строка 9). Это крайне неэффективно. Вы должны сохранить результат ord() в переменной, а затем повторно использовать его в условном выражении. Кроме того, рассмотрите использование === вместо ==, поскольку использование функции == не рекомендуется. Хотя я не обвиняю вас в этом, по иронии судьбы PHP-руководство для ord() показывает использование == в примерах. – xZero

17

$clearstring=filter_var($rawstring, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);

+0

Кажется идеальным для PHP> = 5.2 – user414873

+0

thats Works (Y) – vin

+0

Это, кажется, также стрижет метки. Для меня он удалял <% AnyTextHere%> См. [Фильтры PHP Sanitize] (http://php.net/manual/en/filter.filters.sanitize.php) – ds00424

2

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

Вот мое предложение:

function convert_to_normal_text($text) { 

    $normal_characters = "a-zA-Z0-9\s`[email protected]#$%^&*()_+-={}|:;<>?,.\/\"\'\\\[\]"; 
    $normal_text = preg_replace("/[^$normal_characters]/", '', $text); 

    return $normal_text; 
} 

Затем вы можете использовать его как это:

$before = 'Some "normal characters": Abc123!+, some ASCII characters: ABC+ŤĎ and some non-ASCII characters: Ąąśćł.'; 
$after = convert_to_simple_text($before); 
echo $after; 

Дисплеи:

Some "normal characters": Abc123!+, some ASCII characters: ABC+ and some non-ASCII characters: . 
+1

FYI, Typo on line 4: '$ normal_caracters' => '$ normal_characters' – ds00424

+0

Спасибо @ ds00424. Я уже исправил это. – simhumileco

Смежные вопросы