protected function _extractAttributes($str) {
		$str = preg_replace("/[\x{00a0}\x{200b}]+/u", ' ', $str);
		$attributes = array();
		$patterns = array(
			'name-value-quotes-dble' => '(\w+)\s*=\s*"([^"]*)"',
			'name-value-quotes-sgle' => "(\w+)\s*=\s*'([^']*)'",
			'name-value-quotes-none' => '(\w+)\s*=\s*([^\s\'"]+)',
			'name-quotes-dble' => '"([^"]*)"',
			'name-quotes-sgle' => "'([^']*)'",
			'name-quotes-none' => '(\w+)'
		);
		$pattern = '/' . implode('(?:\s|$)|', $patterns) . '(?:\s|$)/';

		if (!preg_match_all($pattern, $str, $matches, PREG_SET_ORDER)) {
			return $attributes;
		}

		foreach ($matches as $match) {
			if (!empty($match[1])) {
				$attributes[strtolower($match[1])] = stripcslashes($match[2]);
			} else if (!empty($match[3])) {
				$attributes[$match[3]] = stripcslashes($match[4]);
			} else if (!empty($match[5])) {
				$attributes[$match[5]] = stripcslashes($match[6]);
			} else if (!empty($match[7]) && strlen($match[7])) {
				$attributes[] = stripcslashes($match[7]);
			} else if (!empty($match[8])) {
				$attributes[] = stripcslashes($match[8]);
			} else if (!empty($match[9])) {
				$attributes[] = stripcslashes($match[9]);
			}
		}

		return $attributes;
	}