How to know if there one or more Cyrillic symbol in String and count them (Kotlin) - string

I'm working on QR-parser. In my QR I have a field "encoding", which one shows us a string encoding ("1" = w1251, "2" = UTF8, "3" = KOI8-R). I need decode 1, 3 in UTF-8, so it's ok:
private fun checkEncoding(encoding: String, decodedString: String) =
when (encoding) {
"1" -> decodedString.toByteArray(Charset.forName("windows-1251")).toString(Charset.forName("UTF-8"))
"3" -> decodedString.toByteArray(Charset.forName("KOI8-R")).toString(Charset.forName("UTF-8"))
"2" -> decodedString
else -> throw ErrorsBuilder.UNKNOWN_ENCODING_ERROR.unknownEncodingException(decodedString)
}
But sometimes we get wrong QRs, which has encoding = 1, but string in UTF8.
We'd like to work with this situation, maybe anyone can help. We decided to make next logic: if string has Russian symbols -> do nothing with it, it's UTF8. else -> do checkEncoding()
First idea: check if they're Russian letters in string. I did this:
fun main() {
val string1 = "Name=Филиал"
val string2 = "Name=СчеС"
val string3 = "ФФФ"
println(parse2(string1)) //false
println(parse2(string2)) //false
println(parse2(string3)) //true }
fun parse2(string: String): Boolean {
return string.matches("[а-яёА-ЯЁ]+".toRegex())
}
How can u check that string has at least one Russian symbol with many English? Something like matchesAny()?
The second problem that in String "ST00011|Name=СчеС" symbols "Р", "С" are Russian too. I decided to make some counter, which count Russian symbols from string and compare that number with string length.
But I don't know how to perform it.
So maybe u have any Ideas and better solutions for my situation? Or can give me the answer on question from Title?
Thanks a lot

What about a simple regex check:
Regex("[\\u0400-\\u04FF]").containsMatchIn(inputString)

Related

convert string to list of int in kotlin

I have a string = "1337" and I want to convert it to a list of Int, I tried to get every element in the string and convert it to Int like this string[0].toInt but I didn't get the number I get the Ascii value, I can do it with this Character.getNumericValue(number), How I do it without using a built it function? with good complexity?
What do you mean "without using a built in function"?
string[0].toInt gives you the ASCII value of the character because the fun get(index: Int) on String has a return type of Char, and a Char behaves closer to a Number than a String. "0".toInt() == 0 will yield true, but '0'.toInt() == 0 will yield false. The difference being the first one is a string and the second is a character.
A oneliner
string.split("").filterNot { it.isBlank() }.map { it.toInt() }
Explanation: split("") will take the string and give you a list of every character as a string, however, it will give you an empty string at the beginning, which is why we have filterNot { it.isBlank() }, we then can use map to transform every string in our list to Int
If you want something less functional and more imperative that doesn't make use of functions to convert there is this
val ints = mutableListOf<Int>() //make a list to store the values in
for (c: Char in "1234") { //go through all of the characters in the string
val numericValue = c - '0' //subtract the character '0' from the character we are looking at
ints.add(numericValue) //add the Int to the list
}
The reason why c - '0' works is because the ASCII values for the digits are all in numerical order starting with 0, and when we subtract one character from another, we get the difference between their ASCII values.
This will give you some funky results if you give it a string that doesn't have only digits in it, but it will not throw any exceptions.
As in Java and by converting Char to Int you get the ascii equivalence.
You can instead:
val values = "1337".map { it.toString().toInt() }
println(values[0]) // 1
println(values[1]) // 3
// ...
Maybe like this? No-digits are filtered out. The digits are then converted into integers:
val string = "1337"
val xs = string.filter{ it.isDigit() }.map{ it.digitToInt() }
Requires Kotlin 1.4.30 or higher and this option:
#OptIn(ExperimentalStdlibApi::class)

Converting a string to bytes

im fairly new to OCaml, so excuse any stupid mistake.
Im trying to modify the elements of a string, yet it wont allow me, saying it is expecting an expression of type bytes. After doing some reading, I know why, so I tried to convert my string to bytes, with no success. I've looked everywhere on how to convert a string to bytes, but can't seem to find anything. Can someone help me?
There is a function Bytes.of_string that does this.
Bytes.of_string "my string abc";;
- : bytes = Bytes.of_string "my string abc"
It's interesting to note that the toplevel expression printer (the P part of REPL) prints byte values using a Bytes.of_string call.
You can convert back to a string with Bytes.to_string.
# let b = Bytes.of_string "hal9000";;
val b : bytes = Bytes.of_string "hal9000"
# Bytes.to_string (Bytes.map (fun c -> Char.chr (Char.code c + 1)) b);;
- : string = "ibm:111"

Swift string strip all characters but numbers and decimal point?

I have this string:
Some text: $ 12.3 9
I want to get as a result:
12.39
I have found examples on how to keep only numbers, but here I am wanting to keep the decimal point "."
What's a good way to do this in Swift?
This should work (it's a general approach to filtering on a set of characters) :
[EDIT] simplified and adjusted to Swift3
[EDIT] adjusted to Swift4
let text = "$ 123 . 34 .876"
let decimals = Set("0123456789.")
var filtered = String( text.filter{decimals.contains($0)} )
If you need to ignore anything past the second decimal point add this :
filtered = filtered.components(separatedBy:".") // separate on decimal point
.prefix(2) // only keep first two parts
.joined(separator:".") // put parts back together
Easiest and simplest reusable way: you can use this regex replacement option. This replaces all characters except 0 to 9 and dot (.) .
let yourString = "$123. 34"
//pattern says except digits and dot.
let pattern = "[^0-9.]"
do {
let regex = try NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions.CaseInsensitive)
//replace all not required characters with empty string ""
let string_With_Just_Numbers_You_Need = regex.stringByReplacingMatchesInString(yourString, options: NSMatchingOptions.WithTransparentBounds, range: NSMakeRange(0, yourString.characters.count), withTemplate: "")
//your number converted to Double
let convertedToDouble = Double(string_With_Just_Numbers_You_Need)
} catch {
print("Cant convert")
}
One possible solution to the question follows below. If you're working with text fields and currency, however, I suggest you take a look at the thread Leo Dabus linked to.
extension String {
func filterByString(myFilter: String) -> String {
return String(self.characters.filter {
myFilter.containsString(String($0))
})
}
}
var a = "$ 12.3 9"
let myFilter = "0123456789.$"
print(a.filterByString(myFilter)) // $12.39

Lua: how do I split a string (of a varying length) into multiple parts?

I have a string, starting with a number, then a space, then a word of an unknown amount of letters, a space again, and then sometimes another piece of text (which may or may not contain more than one word).
EDIT: the last piece of text is sometimes left out (see example #2)
Using the methods mentioned in the comments, str:find(...) on #2 would return nil.
Example:
"(number) (text) [more text]"
1: "10 HELLO This is a string"
2: "88 BYE"
What I want is to split these strings into a table, inside a table containing more of these split strings, like this:
{
[(number)] = { [1] = (text), [2] = (more text) }
[10] = { [1] = "HELLO", [2] = "This is a string" }
}
I have tried several methods, but none of them give me the desired result.
One of the methods I tried, for example, was splitting the string on whitespaces. But that resulted in:
{
[10] = { [1] = "HELLO", [2] = "This", ... [4] = "string" }
}
Thanks in advance.
Using various Lua string patterns, achieving the desired result is quite easy.
For eg.
function CustomMatching( sVar )
local tReturn = {}
local _, _, iNumber, sWord, sRemain = sVar:find( "^(%d+)%s(%a+)%s(.+)" )
tReturn[tonumber(iNumber)] = { sWord, sRemain }
return tReturn
end
And to call it:
local sVar = "10 HELLO This is a string"
local tMyTable = CustomMatching( sVar )
In the find() method the pattern "^(%d+)%s(%a+)%s(.+)" means:
Find and store all digits(%d) until a space is encountered.
Find and store all letters(%a) until a space is encountered.
Find and store all characters until the end of string is reached.
EDIT
Changed tReturn[iNumber] to tReturn[tonumber(iNumber)] as per the discussion in comments.
You can use the string.match method with an appropriate pattern:
local n, w, str = ('10 HELLO This is a string'):match'^(%d+)%s+(%S+)%s+(.*)$'
your_table[tonumber(n)] = {w, str}

Is it possible to compare two characters in Processing?

I am a novice programmer and I am trying to compare two characters from different strings, such that I can give an arbitrary index from each string and check to see if they match. From the processing website it seems that you can compare two strings, which I have done, but when I try to do so with characters it seems that the arguments (char,char) are not applicable. Can someone tell me where I am going wrong? Thanks.
You can use String's charAt() method/function to get character from each string at the desired index, then simply compare:
String s1 = ":)";
String s2 = ";)";
void setup(){
println(CompareCharAt(s1,s2,0));
println(CompareCharAt(s1,s2,1));
}
boolean CompareCharAt(String str1,String str2,int index){
return s1.charAt(index) == s2.charAt(index);
}
Note that when you're comparing strings == doesn't help, you need to use String's equal()
String s1 = ":)";
String s2 = ";)";
println(s1.equals(s2));
println(s1.equals(":)"));
Also, if data comes from external sources, it's usually a good idea to compare both strings at using the same case:
println("MyString".equals("myString"));
println("MyString".toLowerCase().equals("myString".toLowerCase()));
maybe you can pass the argument after converting(typecasting) the char to string.
(string(char),string(char))
Yep. Just use == as it gets interpreted as a char datatype.
This is assuming you've split the char from the String...
char a = 'a';
char b = 'a';
if(a == b) {
// etc
}
As mentioned above, use .equals() for String comparison.
String a = "a";
String b = "a";
if(a.equals(b)) {
// etc
}
Also, the proper way to cast a char as a String is str() not string()

Resources