I'm trying to find out if a string has cyrilic cha...
# lucee
m
I'm trying to find out if a string has cyrilic characters. While the regex is fine (https://regex101.com/r/ZNbAqo/1), it doesn't work in lucee, nor acf:
Copy code
<cfscript>
function containsCyrillic(text) {
    return REFind("[\u0400-\u04FF]", text) > 0;
}

text = "Пример";

if (containsCyrillic(text)) {
    WriteOutput("Der Text enthält kyrillische Zeichen.<br>");
} else {
    WriteOutput("Der Text enthält keine kyrillischen Zeichen.<br>");
}
</cfscript>
Any idea what is wrong here? I can use ``javaCast("string",`
arguments.searchTerm).matches(".*[\p{InCyrillic}].*")
which works, but wonder if this is just a bug or is the problem in front of the monitor.
e
Break your strings down to their base ascii characters. then figure out what to do next.. <cfset text = "I love cf with some non-ASCII characters: Пример">
Copy code
<!--- Convert the string to a byte array in UTF-8 encoding --->
<cfset byteArray = createObject("java", "java.nio.charset.StandardCharsets").UTF_8.encode(text).array()>

<!--- Use the juniversalchardet library to detect encoding --->
<cfset charsetDetector = createObject("java", "org.mozilla.universalchardet.UniversalDetector").new()>
<cfset charsetDetector.handleData(byteArray, 0, arrayLen(byteArray))>
<cfset charsetDetector.dataEnd()>

<!--- check encoding --->
<cfset detectedEncoding = charsetDetector.getDetectedCharset()>
b
@jeffcoughlin Can you move your reply here to this thread? 🙂
j
Sup Brad
👋 1
Sure, I'll re-paste if that's okay
b
sure
j
It's not a bug, but a limitation of the regex engine used in Lucee and ColdFusion. Lucee does not support Unicode properties (
\p{}
) in
REFind()
and does not properly interpret
\u0400-\u04FF
. Using Java’s
matches()
method is the most reliable workaround.. Lucee uses Apache ORO for regex, which does not fully support Unicode character classes in the same way as Java’s
Pattern
class. Since you already have a working solution using Java’s
matches()
with
\p{InCyrillic}
, another way to fix this in Lucee (without switching to Java regex) is to use
REFindNoCase()
with
charset="UTF-8"
and specify the range explicitly. [2:18 PM] jeffcoughlin Option 1: Using REFInd():
Copy code
function containsCyrillic(text) {
    return REFind("[\x{0400}-\x{04FF}]", text, "ALL") > 0;
}

text = "Пример";

if (containsCyrillic(text)) {
    WriteOutput("Der Text enthält kyrillische Zeichen.<br>");
} else {
    WriteOutput("Der Text enthält keine kyrillischen Zeichen.<br>");
}
[2:19 PM] jeffcoughlin Option 2: Using
javaCast("string", text).matches()
(Works in Lucee) Since Lucee runs on Java, you can leverage Java’s Unicode support:
Copy code
function containsCyrillic(text) {
    return javaCast("string", text).matches(".*\\p{InCyrillic}.*");
}

text = "Пример";

if (containsCyrillic(text)) {
    WriteOutput("Der Text enthält kyrillische Zeichen.<br>");
} else {
    WriteOutput("Der Text enthält keine kyrillischen Zeichen.<br>");
}
[2:20 PM] jeffcoughlin My advice is to use option 2. It's the most reliable solution because Java's regex engine natively supports Unicode character properties. [2:21 PM] jeffcoughlin Удачи!
👍 1
b
if you hurry you can delete the main post in the channel before the 30 minute window kids in and locks your messages, lol
j
Oh, should I delete it?
👍 1
b
Well, it's really only needed here in the thread 🙂
In a channel with nearly 2,000 people, it's best to keep replies in a thread so it doesn't muddy the main channel
👍 1
j
done
🙏 1
I haven't been on the cfml slack server in a very long time. Just popped my head in while I'm job searching (just ended a contract the other day). Saw his question and thought I'd reply (and maybe brush up on my Russian a little 🙂 )
b
Spasibo
🙂 1
j
btw, I didn't mean to tread on your response to the problem.
a
Very nice and detailed analysis though, @jeffcoughlin 👋
☝️ 2
r
Late for party, but this code works:
<*cfset* cyrvar = "Hello in Russian is Привет" /> <*cfset* f = reFindNoCase("[а-я]+", cyrvar) />
а-я are first and last letters of Russian alphabet, lucee cfm template is in UTF-8, optionally may use <*cfprocessingdirective* pageEncoding="utf-8" />