{@inheritdoc}
based on: http://stackoverflow.com/questions/3371697/replacing-accented-characters-php
and: http://stackoverflow.com/questions/3230012/replacing-accents-with-their-counterparts
481158
public function replaceUmlauts($string, $ignoreCase = true)
    {
        $umlauts = array(
            'A' => array(
                'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ă'
            ),
            'a' => array(
                'à', 'á', 'â', 'ã', 'ä', 'å', 'ă', 'æ'
            ),
            'B' => array(
                'Þ'
            ),
            'b' => array(
                'þ'
            ),
            'C' => array(
                'Ç'
            ),
            'c' => array(
                'ç'
            ),
            'E' => array(
                'È', 'É', 'Ê', 'Ë'
            ),
            'e' => array(
                'è', 'é', 'ê', 'ë'
            ),
            'G' => array(
                'Ğ'
            ),
            'g' => array(
                'ğ'
            ),
            'I' => array(
                'Ì', 'Í', 'Î', 'Ï', 'İ'
            ),
            'i' => array(
                'ı', 'ì', 'í', 'î', 'ï'
            ),
            'N' => array(
                'Ñ'
            ),
            'n' => array(
                'ñ'
            ),
            'O' => array(
                'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø'
            ),
            'o' => array(
                'ö', 'ø', 'ð', 'ò', 'ó', 'ô', 'õ'
            ),
            'S' => array(
                'Š', 'Ş', 'Ș'
            ),
            's' => array(
                'š', 'ș', 'ş'
            ),
            'sz' => array(
                'ß'
            ),
            'T' => array(
                'Ț'
            ),
            't' => array(
                'ț'
            ),
            'U' => array(
                'Ù', 'Ú', 'Û', 'Ü'
            ),
            'u' => array(
                'ù', 'ú', 'û', 'ü'
            ),
            'Y' => array(
                'Ý'
            ),
            'y' => array(
                'ý', 'ý', 'ÿ'
            ),
            'Z' => array(
                'Ž'
            ),
            'z' => array(
                'ž'
            )
        );

        foreach ($umlauts as $replace => $searches) {
            $string = $this->string
                ->setValue($string)
                ->replace($searches, $replace, $ignoreCase)
                ->getValue();
        }

        return $string;
    }
1144947
function generateCharsetMappingTable( $unicodeTable, $charset )
    {
        $codec = eZTextCodec::instance( 'unicode', $charset );
        if ( !$codec )
        {
            eZDebug::writeError( "Failed to create textcodec for charset '$charset'" );
            return false;
        }

        $charsetTable = array();
        foreach ( $unicodeTable as $match => $replacement )
        {
            $matchLocal = $codec->convertString( array( $match ) );
            if ( is_array( $replacement ) )
            {
                $replacementLocal = $codec->convertString( $replacement );
            }
            else
            {
                $replacementLocal = $codec->convertString( array( $replacement ) );
            }
            $charsetTable[$matchLocal] = $replacementLocal;
        }

        // Make sure longer string entries are placed before the shorter ones
        // This is very important when working with utf8 which have
        // variable length for characters
        krsort( $charsetTable );
        return $charsetTable;
    }
1148052
def strip_accents(s, encoding= 'utf-8'):
    """"""
    if sys.version < '3':
        if isinstance(s,unicode):
           return unicodedata.normalize('NFKD', s).encode('ASCII', 'ignore')
        else:
           return unicodedata.normalize('NFKD', unicode(s,encoding)).encode('ASCII', 'ignore')
    else:
        if isinstance(s,bytes): s = str(s,encoding)
        return str(unicodedata.normalize('NFKD', s).encode('ASCII', 'ignore'),'ascii')
197268
private function doReplacements($contents)
	{
		// Replace variables
		if (isset($this->replacements) && count($this->replacements) > 0)
		{
			foreach ($this->replacements as $k => $v)
			{
				if (is_array($v))
				{
					foreach ($v as $replacement)
					{
						foreach ($replacement as $key => $value)
						{
							$contents = preg_replace("/%={$key}=%/", $value, $contents, 1);
						}
					}
				}
				else
				{
					// See if there are any instances of our key with special qualifiers
					if (preg_match_all("/%={$k}\+([[:alpha:]]+)=%/", $contents, $matches) && isset($matches[1]))
					{
						// Remove complete match
						unset($matches[0]);
						foreach ($matches[1] as $match)
						{
							switch ($match)
							{
								// Upper case word
								case 'uc':
									$value = strtoupper($v);
									break;
								// Upper case first character
								case 'ucf':
									$value = ucfirst($v);
									break;
								// Upper case first character and plural
								case 'ucfp':
									$value = ucfirst(Inflector::pluralize($v));
									break;
								// Plural form
								case 'p':
									$value = Inflector::pluralize($v);
									break;
							}

							$contents = str_replace("%={$k}+{$match}=%", $value, $contents);
						}
					}

					// Now do all basic replacements
					$contents = str_replace("%={$k}=%", $v, $contents);

					if ($this->doBlindReplacements)
					{
						$contents = str_replace($k, $v, $contents);
					}
				}
			}
		}

		// Now parse for nested templates
		preg_match_all('/\$\^[[:alpha:]\.]*\^\$/', $contents, $matches, PREG_SET_ORDER);

		if (isset($matches) && count($matches) > 0)
		{
			foreach ($matches as $match)
			{
				foreach ($match as $key)
				{
					// Get template contents
					$keyReal = preg_replace('/\$\^([[:alpha:]\.]*)\^\$/', '$1', $key);
					$subPath = __DIR__ . DS . 'Scaffolding' . DS . 'Templates' . DS . $this->getType() . '.' . $keyReal . '.tmpl';

					if (!is_file($subPath))
					{
						continue;
					}

					$subTmpl = file_get_contents($subPath);

					if (isset($this->replacements[$keyReal]) && is_array($this->replacements[$keyReal]))
					{
						$count    = count($this->replacements[$keyReal]);
						$repeat   = str_repeat($key, $count);
						$contents = str_replace($key, $repeat, $contents);
					}

					$contents = str_replace($key, $subTmpl, $contents);
					$contents = $this->doReplacements($contents);
				}
			}
		}

		return $contents;
	}
496597
private function _transliterateDanish ($s)
    {
        $table = array(
        'æ' => 'ae', 
        'ø' => 'oe', 
        'å' => 'aa', 
        'Æ' => 'Ae', 
        'Ø' => 'Oe', 
        'Å' => 'Aa' 
        );
        return strtr($s, $table);
    }
1130186
protected static function replacePHP(&$php)
	{
		// Expression that matches a $node->getAttribute() call and captures its string argument
		$getAttribute = "\\\$node->getAttribute\\(('[^']+')\\)";

		// Expression that matches a single-quoted string literal
		$string       = "'(?:[^\\\\']|\\\\.)*+'";

		$replacements = [
			'$this->out' => '$html',

			// An attribute value escaped as ENT_NOQUOTES. We only need to unescape quotes
			'(htmlspecialchars\\(' . $getAttribute . ',' . ENT_NOQUOTES . '\\))'
				=> "str_replace('&quot;','\"',\$attributes[\$1])",

			// One or several attribute values escaped as ENT_COMPAT can be used as-is
			'(htmlspecialchars\\((' . $getAttribute . '(?:\\.' . $getAttribute . ')*),' . ENT_COMPAT . '\\))'
				=> function ($m) use ($getAttribute)
				{
					return preg_replace('(' . $getAttribute . ')', '$attributes[$1]', $m[1]);
				},

			// Character replacement can be performed directly on the escaped value provided that it
			// is then escaped as ENT_COMPAT and that replacements do not interfere with the escaping
			// of the characters &<>" or their representation &amp;&lt;&gt;&quot;
			'(htmlspecialchars\\(strtr\\(' . $getAttribute . ",('[^\"&\\\\';<>aglmopqtu]+'),('[^\"&\\\\'<>]+')\\)," . ENT_COMPAT . '\\))'
				=> 'strtr($attributes[$1],$2,$3)',

			// A comparison between two attributes. No need to unescape
			'(' . $getAttribute . '(!?=+)' . $getAttribute . ')'
				=> '$attributes[$1]$2$attributes[$3]',

			// A comparison between an attribute and a literal string. Rather than unescape the
			// attribute value, we escape the literal. This applies to comparisons using XPath's
			// contains() as well (translated to PHP's strpos())
			'(' . $getAttribute . '===(' . $string . '))s'
				=> function ($m)
				{
					return '$attributes[' . $m[1] . ']===' . htmlspecialchars($m[2], ENT_COMPAT);
				},

			'((' . $string . ')===' . $getAttribute . ')s'
				=> function ($m)
				{
					return htmlspecialchars($m[1], ENT_COMPAT) . '===$attributes[' . $m[2] . ']';
				},

			'(strpos\\(' . $getAttribute . ',(' . $string . ')\\)([!=]==(?:0|false)))s'
				=> function ($m)
				{
					return 'strpos($attributes[' . $m[1] . "]," . htmlspecialchars($m[2], ENT_COMPAT) . ')' . $m[3];
				},

			'(strpos\\((' . $string . '),' . $getAttribute . '\\)([!=]==(?:0|false)))s'
				=> function ($m)
				{
					return 'strpos(' . htmlspecialchars($m[1], ENT_COMPAT) . ',$attributes[' . $m[2] . '])' . $m[3];
				},

			// An attribute value used in an arithmetic comparison or operation does not need to be
			// unescaped. The same applies to empty(), isset() and conditionals
			'(' . $getAttribute . '(?=(?:==|[-+*])\\d+))'  => '$attributes[$1]',
			'(\\b(\\d+(?:==|[-+*]))' . $getAttribute . ')' => '$1$attributes[$2]',
			'(empty\\(' . $getAttribute . '\\))'           => 'empty($attributes[$1])',
			"(\\\$node->hasAttribute\\(('[^']+')\\))"      => 'isset($attributes[$1])',
			'if($node->attributes->length)'                => 'if($this->hasNonNullValues($attributes))',

			// In all other situations, unescape the attribute value before use
			'(' . $getAttribute . ')' => 'htmlspecialchars_decode($attributes[$1])'
		];

		foreach ($replacements as $match => $replace)
		{
			if ($replace instanceof Closure)
			{
				$php = preg_replace_callback($match, $replace, $php);
			}
			elseif ($match[0] === '(')
			{
				$php = preg_replace($match, $replace, $php);
			}
			else
			{
				$php = str_replace($match, $replace, $php);
			}
		}
	}
711487
public static function accent(String $str) : String
    {
        $accent = array_merge(Config::get('Expressions', 'accentChars') ?: [], self::$accentChars);

        $accent = Datatype::multikey($accent);

        return str_replace(array_keys($accent), array_values($accent), $str);
    }
437918
function convert($txt) {
		$txt=preg_replace_callback(
			'/(<code.*?>.+?<\/code>|'.
			'<[^>\n]+>|\([^\n\)]+\)|"[^"\n]+")|'.
			'\\\\(.)/s',
			function($expr) {
				// Process escaped characters
				return empty($expr[1])?$expr[2]:$expr[1];
			},
			$this->build(preg_replace('/\r\n|\r/',"\n",$txt))
		);
		return $this->snip($txt);
	}
135272
function fix_eol($str) {
      $str = str_replace("\r\n", "\n", $str);
      $str = str_replace("\r", "\n", $str);
      $str = str_replace("\n", "\r\n", $str);
      return $str;
   }
776444
def latinize(value):
    
    def replace_double_character(match):
        search = ('Θ Χ Ψ '
                  'θ χ ψ '
                  'ΟΥ ΑΥ ΕΥ '
                  'Ου Αυ Ευ '
                  'ου αυ ευ').split()
        replace = ('TH CH PS '
                   'th ch ps '
                   'OU AU EU '
                   'Ou Au Eu '
                   'ou au eu').split()
        matched = match.group(0)
        if matched in search:
            return replace[search.index(matched)]
        return matched

    search = 'ΑΒΓΔΕΖΗΙΚΛΜΝΞΟΠΡΣΣΤΥΦΩαβγδεζηικλμνξοπρσςτυφω'
    replace = 'AVGDEZIIKLMNXOPRSSTUFOavgdeziiklmnxoprsstyfo'

    def replace_greek_character(match):
        matched = list(match.group(0))
        value = map(lambda l: replace[search.find(l)], matched)
        return ''.join(value)

    return re.sub(r'[{0}]+'.format(search),
                  replace_greek_character, re.sub(
        r'([ΘΧΨθχψ]+|ΟΥ|ΑΥ|ΕΥ|Ου|Αυ|Ευ|ου|αυ|ευ)',
        replace_double_character,
        remove_accents(value)))
583160
function phpEscape(s) {
  var result = '"';
  for (let cp of UnicodeUtils.getCodePoints(s)) {
    let special = specialEscape[cp];
    if (special !== undefined) {
      result += special;
    } else if (cp >= 0x20 && cp <= 0x7e) {
      result += String.fromCodePoint(cp);
    } else if (cp <= 0xFFFF) {
      result += '\\u{' + zeroPaddedHex(cp, 4) + '}';
    } else {
      result += '\\u{' + zeroPaddedHex(cp, 6) + '}';
    }
  }
  result += '"';
  return result;
}
146537
protected function replace_square_brackets_in_smilies()
	{
		// Replace all [ that are inside of <> because they belong to smilies
		if (utf8_strpos($this->message, '<') !== false)
		{
			$this->bracket_replacement = '{' . md5($this->message) . '}';
			while (utf8_strpos($this->message, $this->bracket_replacement) !== false)
			{
				$this->bracket_replacement = '{' . $this->bracket_replacement . '}';
			}
			$smilie_starts = explode('<', $this->message);
			$new_message = array();
			foreach ($smilie_starts as $smilie_test)
			{
				$find_end = explode('>', $smilie_test);
				if (sizeof($find_end) > 1)
				{
					$find_end[0] = str_replace('[', $this->bracket_replacement, $find_end[0]);
					$new_message[] = implode('>', $find_end);
				}
				else
				{
					$new_message[] = $smilie_test;
				}
			}
			$this->message = implode('<', $new_message);
			//$this->message = preg_replace('/(\<[^>]*)\[(?=[^<]*\>)/', $this->bracket_replacement, $this->message);
		}
	}
592373
def add_accent_char(char, accent):
    
    if char == "":
        return ""
    case = char.isupper()
    char = char.lower()
    index = utils.VOWELS.find(char)
    if (index != -1):
        index = index - index % 6 + 5
        char = utils.VOWELS[index - accent]
    return utils.change_case(char, case)
1351591
public static function removeAccent($string)
    {
        $replace = [
            'ъ'=> '-', 'Ь'=>'-', 'Ъ'=>'-', 'ь'=>'-',
            'Ă'=> 'A', 'Ą'=>'A', 'À'=>'A', 'Ã'=>'A', 'Á'=>'A', 'Æ'=>'A', 'Â'=>'A', 'Å'=>'A', 'Ä'=>'Ae',
            'Þ'=> 'B',
            'Ć'=> 'C', 'ץ'=>'C', 'Ç'=>'C',
            'È'=> 'E', 'Ę'=>'E', 'É'=>'E', 'Ë'=>'E', 'Ê'=>'E',
            'Ğ'=> 'G',
            'İ'=> 'I', 'Ï'=>'I', 'Î'=>'I', 'Í'=>'I', 'Ì'=>'I',
            'Ł'=> 'L',
            'Ñ'=> 'N', 'Ń'=>'N',
            'Ø'=> 'O', 'Ó'=>'O', 'Ò'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'Oe',
            'Ş'=> 'S', 'Ś'=>'S', 'Ș'=>'S', 'Š'=>'S',
            'Ț'=> 'T',
            'Ù'=> 'U', 'Û'=>'U', 'Ú'=>'U', 'Ü'=>'Ue',
            'Ý'=> 'Y',
            'Ź'=> 'Z', 'Ž'=>'Z', 'Ż'=>'Z',
            'â'=> 'a', 'ǎ'=>'a', 'ą'=>'a', 'á'=>'a', 'ă'=>'a', 'ã'=>'a', 'Ǎ'=>'a', 'а'=>'a', 'А'=>'a', 'å'=>'a', 'à'=>'a', 'א'=>'a', 'Ǻ'=>'a', 'Ā'=>'a', 'ǻ'=>'a', 'ā'=>'a', 'ä'=>'ae', 'æ'=>'ae', 'Ǽ'=>'ae', 'ǽ'=>'ae',
            'б'=> 'b', 'ב'=>'b', 'Б'=>'b', 'þ'=>'b',
            'ĉ'=> 'c', 'Ĉ'=>'c', 'Ċ'=>'c', 'ć'=>'c', 'ç'=>'c', 'ц'=>'c', 'צ'=>'c', 'ċ'=>'c', 'Ц'=>'c', 'Č'=>'c', 'č'=>'c', 'Ч'=>'ch', 'ч'=>'ch',
            'ד'=> 'd', 'ď'=>'d', 'Đ'=>'d', 'Ď'=>'d', 'đ'=>'d', 'д'=>'d', 'Д'=>'D', 'ð'=>'d',
            'є'=> 'e', 'ע'=>'e', 'е'=>'e', 'Е'=>'e', 'Ə'=>'e', 'ę'=>'e', 'ĕ'=>'e', 'ē'=>'e', 'Ē'=>'e', 'Ė'=>'e', 'ė'=>'e', 'ě'=>'e', 'Ě'=>'e', 'Є'=>'e', 'Ĕ'=>'e', 'ê'=>'e', 'ə'=>'e', 'è'=>'e', 'ë'=>'e', 'é'=>'e',
            'ф'=> 'f', 'ƒ'=>'f', 'Ф'=>'f',
            'ġ'=> 'g', 'Ģ'=>'g', 'Ġ'=>'g', 'Ĝ'=>'g', 'Г'=>'g', 'г'=>'g', 'ĝ'=>'g', 'ğ'=>'g', 'ג'=>'g', 'Ґ'=>'g', 'ґ'=>'g', 'ģ'=>'g',
            'ח'=> 'h', 'ħ'=>'h', 'Х'=>'h', 'Ħ'=>'h', 'Ĥ'=>'h', 'ĥ'=>'h', 'х'=>'h', 'ה'=>'h',
            'î'=> 'i', 'ï'=>'i', 'í'=>'i', 'ì'=>'i', 'į'=>'i', 'ĭ'=>'i', 'ı'=>'i', 'Ĭ'=>'i', 'И'=>'i', 'ĩ'=>'i', 'ǐ'=>'i', 'Ĩ'=>'i', 'Ǐ'=>'i', 'и'=>'i', 'Į'=>'i', 'י'=>'i', 'Ї'=>'i', 'Ī'=>'i', 'І'=>'i', 'ї'=>'i', 'і'=>'i', 'ī'=>'i', 'ĳ'=>'ij', 'Ĳ'=>'ij',
            'й'=> 'j', 'Й'=>'j', 'Ĵ'=>'j', 'ĵ'=>'j', 'я'=>'ja', 'Я'=>'ja', 'Э'=>'je', 'э'=>'je', 'ё'=>'jo', 'Ё'=>'jo', 'ю'=>'ju', 'Ю'=>'ju',
            'ĸ'=> 'k', 'כ'=>'k', 'Ķ'=>'k', 'К'=>'k', 'к'=>'k', 'ķ'=>'k', 'ך'=>'k',
            'Ŀ'=> 'l', 'ŀ'=>'l', 'Л'=>'l', 'ł'=>'l', 'ļ'=>'l', 'ĺ'=>'l', 'Ĺ'=>'l', 'Ļ'=>'l', 'л'=>'l', 'Ľ'=>'l', 'ľ'=>'l', 'ל'=>'l',
            'מ'=> 'm', 'М'=>'m', 'ם'=>'m', 'м'=>'m',
            // 'ñ'=>'n', // for spanish cono != coño
            'н'=> 'n', 'Ņ'=>'n', 'ן'=>'n', 'ŋ'=>'n', 'נ'=>'n', 'Н'=>'n', 'ń'=>'n',
            'Ŋ'=> 'n', 'ņ'=>'n', 'ŉ'=>'n', 'Ň'=>'n', 'ň'=>'n',
            'о'=> 'o', 'О'=>'o', 'ő'=>'o', 'õ'=>'o', 'ô'=>'o', 'Ő'=>'o', 'ŏ'=>'o', 'Ŏ'=>'o', 'Ō'=>'o', 'ō'=>'o', 'ø'=>'o', 'ǿ'=>'o', 'ǒ'=>'o', 'ò'=>'o', 'Ǿ'=>'o', 'Ǒ'=>'o', 'ơ'=>'o', 'ó'=>'o', 'Ơ'=>'o', 'œ'=>'oe', 'Œ'=>'oe', 'ö'=>'oe',
            'פ'=> 'p', 'ף'=>'p', 'п'=>'p', 'П'=>'p',
            'ק'=> 'q',
            'ŕ'=> 'r', 'ř'=>'r', 'Ř'=>'r', 'ŗ'=>'r', 'Ŗ'=>'r', 'ר'=>'r', 'Ŕ'=>'r', 'Р'=>'r', 'р'=>'r',
            'ș'=> 's', 'с'=>'s', 'Ŝ'=>'s', 'š'=>'s', 'ś'=>'s', 'ס'=>'s', 'ş'=>'s', 'С'=>'s', 'ŝ'=>'s', 'Щ'=>'sch', 'щ'=>'sch', 'ш'=>'sh', 'Ш'=>'sh', 'ß'=>'ss',
            'т'=> 't', 'ט'=>'t', 'ŧ'=>'t', 'ת'=>'t', 'ť'=>'t', 'ţ'=>'t', 'Ţ'=>'t', 'Т'=>'t', 'ț'=>'t', 'Ŧ'=>'t', 'Ť'=>'t', '™'=>'tm',
            'ū'=> 'u', 'у'=>'u', 'Ũ'=>'u', 'ũ'=>'u', 'Ư'=>'u', 'ư'=>'u', 'Ū'=>'u', 'Ǔ'=>'u', 'ų'=>'u', 'Ų'=>'u', 'ŭ'=>'u', 'Ŭ'=>'u', 'Ů'=>'u', 'ů'=>'u', 'ű'=>'u', 'Ű'=>'u', 'Ǖ'=>'u', 'ǔ'=>'u', 'Ǜ'=>'u', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'У'=>'u', 'ǚ'=>'u', 'ǜ'=>'u', 'Ǚ'=>'u', 'Ǘ'=>'u', 'ǖ'=>'u', 'ǘ'=>'u', 'ü'=>'ue',
            'в'=> 'v', 'ו'=>'v', 'В'=>'v',
            'ש'=> 'w', 'ŵ'=>'w', 'Ŵ'=>'w',
            'ы'=> 'y', 'ŷ'=>'y', 'ý'=>'y', 'ÿ'=>'y', 'Ÿ'=>'y', 'Ŷ'=>'y',
            'Ы'=> 'y', 'ž'=>'z', 'З'=>'z', 'з'=>'z', 'ź'=>'z', 'ז'=>'z', 'ż'=>'z', 'ſ'=>'z', 'Ж'=>'zh', 'ж'=>'zh',  'ά' => 'α', 'έ' => 'ε', 'ή' => 'η', 'ί' => 'ι', 'ό' => 'ο', 'ύ' => 'υ', 'ώ' => 'ω',
        ];

        return strtr($string, $replace);
    }
1052979
function unicodeToUtf8() : SplString
    {

        $string = preg_replace_callback( '/\\\\u([0-9a-f]{4})/i', function( $matches ){
            return mb_convert_encoding( pack( "H*", $matches[1] ), "UTF-8", "UCS-2BE" );
        }, $this->__toString() );
        return $this->setString( $string );
    }
1108046
public static function normalizeChars($string)
    {
        $normalizeChars = array(
            'Á' => 'A', 'À' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Å' => 'A', 'Ä' => 'A', 'Æ' => 'AE', 'Ç' => 'C',
            'É' => 'E', 'È' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Í' => 'I', 'Ì' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ð' => 'Eth',
            'Ñ' => 'N', 'Ó' => 'O', 'Ò' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O',
            'Ú' => 'U', 'Ù' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ý' => 'Y', 'Ŕ' => 'R',

            'á' => 'a', 'à' => 'a', 'â' => 'a', 'ã' => 'a', 'å' => 'a', 'ä' => 'a', 'æ' => 'ae', 'ç' => 'c',
            'é' => 'e', 'è' => 'e', 'ê' => 'e', 'ë' => 'e', 'í' => 'i', 'ì' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'eth',
            'ñ' => 'n', 'ó' => 'o', 'ò' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o',
            'ú' => 'u', 'ù' => 'u', 'û' => 'u', 'ü' => 'u', 'ý' => 'y', 'ŕ' => 'r', 'ÿ' => 'y',

            'ß' => 'sz', 'þ' => 'thorn', 'º' => '', 'ª' => '', '°' => '',
        );
        return preg_replace('/[^0-9a-zA-Z !*\-$\(\)\[\]\{\},.;:\/\\#%&@+=]/', '', strtr($string, $normalizeChars));
    }
848282
protected function _encodeString(&$string)
    {
        // Escape these characters with a backslash or unicode escape:
        // " \ / \n \r \t \b \f
        $search  = array('\\', "\n", "\t", "\r", "\b", "\f", '"', '\'', '&', '<', '>', '/');
        $replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\\u0022', '\\u0027', '\\u0026',  '\\u003C', '\\u003E', '\\/');
        $string  = str_replace($search, $replace, $string);

        // Escape certain ASCII characters:
        // 0x08 => \b
        // 0x0c => \f
        $string = str_replace(array(chr(0x08), chr(0x0C)), array('\b', '\f'), $string);
        $string = self::encodeUnicodeString($string);

        return '"' . $string . '"';
    }