Actually you don't even need the mb_string extension:
if (strlen($string) != strlen(utf8_decode($string)))
{
echo 'is unicode';
}
And to find the code point of a given character:
$ord = unpack('N', mb_convert_encoding($string, 'UCS-4BE', 'UTF-8'));
echo $ord[1];
Answer from Alix Axel on Stack OverflowActually you don't even need the mb_string extension:
if (strlen($string) != strlen(utf8_decode($string)))
{
echo 'is unicode';
}
And to find the code point of a given character:
$ord = unpack('N', mb_convert_encoding($string, 'UCS-4BE', 'UTF-8'));
echo $ord[1];
you can try with
mb_check_encoding($s,"UTF-8")
link
I found it more useful to detect if any character falls out of the list
if(preg_match('/[^\x20-\x7e]/', $string))
You can use mb_detect_encoding and check for ASCII:
mb_detect_encoding($str, 'ASCII', true)
This will return false if $str contains at least one non-ASCI character (byte value > 0x7F).
I want to explain why your attempts with regex weren't working.
Firstly, I notice ereg in your tags for this question. Please note that PHP's ereg_ functions have been deprecated; you should only use the preg_ functions.
Now, if you want to use regex for this sort of thing, you would typically use a negated character class to define a list of characters you want to allow, and then look for anything else.
A character class is a list of characters enclosed in square brackets. You can negate a character class by adding a carat symbol to the start of it. So if you wanted a string that contained only 'A', 'B' or 'C', and you wanted to get warned about strings which contained anything else, you could use something like this:
$result = preg_match("/[^ABC]/",$mystring);
Your example is basically the same (but with more characters to test, obviously), except for two points: Firstly you have characters in your list which are reserved characters in Regex, and secondly, you are using non-Ascii characters.
The Regex reserved characters can be dealt with by escaping them with a leading back-slash. You just need to know what characters are reserved. Looking at your list, I see ?, /, . and +.
The second point explains why you couldn't get it working with ereg, because the ereg functions don't support unicode. Switch to using the preg functions instead, and you'll have more luck.
You still need to specify to the regex engine that you're looking for a unicode characters. This is done by adding the u modifier to the end of the regex string.
So a shortened version of your query might look like this:
$result = preg_match("/[^èΛ¤4DTdt]/u",$mystring);
It looks like you're including new lines in your list of characters, so you may also want to add the multi-line modifier m alongside that u.
For characters which can't be written (or indeed for any character, if it's easier), you can add escape sequences for their unicode character codes. Use \uFFFF where FFFF is the hex unicode reference for the character you want to match -- eg \u00E0 matches à.
I hope that gives you a better insight into regular expressions. I should add that I'm not saying that regex is necessarily the best solution to this question, nor necessarily the only solution. I have tried to make it perform optimally by using the negated character class (which means it'll fail as soon as it finds a non-matching character, and should prevent the kind of excessive backtracking which can cause regex expressions to be quite slow sometimes), so it should be reasonably performant, but I haven't tested it against other solutions.
As far as you're concerned for single byte charsets, you can do it with string functions:
$charset = 'abc';
$test = 'abcd';
$ofCharset = strlen($test) === strspn($test, $charset); # FALSE
Otherwise you must split your string into array entries of one char each and then compare against a character table which could be a keyed array as well containing the character of the charset as key.
Nevertheless, as it is visible from your question with closer attention, the character set you're asking about is the basic character set of GSM 03.38. It's 7bit, so you can generate the charset array quickly and implode it into a string for strspn():
// alternative form:
// $characters = implode(range("\0", "\177"));
$characters = implode('', range("\0", "\177"));
$result = strlen($string) === strspn($string, $characters);
assert(is_bool($result));
In case you've got the multibyte string extension (mb_* family of functions) available, you can check the string with even less setup:
$test = 'abcd';
$ofCharset = mb_check_encoding($test, 'ASCII') # TRUE
This works because ASCII is 7bit as well and can be used as a stand-in.
Don't reinvent the wheel. There is a builtin function for that task: mb_check_encoding().
mb_check_encoding($string, 'UTF-8');
Just a side note:
You cannot determine if a given string is encoded in UTF-8. You only can determine if a given string is definitively not encoded in UTF-8. Please see a related question here:
You cannot detect if a given string (or byte sequence) is a UTF-8 encoded text as for example each and every series of UTF-8 octets is also a valid (if nonsensical) series of Latin-1 (or some other encoding) octets. However not every series of valid Latin-1 octets are valid UTF-8 series.