iman kazemayni
iman kazemayni

Reputation: 1343

Check or validation Persian(Farsi) string swift

I searched over web pages and stack overflow about validation of a Persian(Farsi) language string. Most of them have mentioned Arabic letters. Also, I want to know if my string is fully Persian(not contain). for example, these strings are Persian:

"چهار راه"

"خیابان."

And These are not:

"خیابان 5"

"چرا copy کردی؟"

Also, just Persian or Arabic digits are allowed. There are exceptions about [.,-!] characters(because keyboards are not supported these characters in Persian)

UPDATE: I explained a swift version of using regex and predicate in my answer.

Upvotes: 2

Views: 1350

Answers (2)

iman kazemayni
iman kazemayni

Reputation: 1343

After a period I could find a better way:

extension String {
 var isPersian: Bool {
        let predicate = NSPredicate(format: "SELF MATCHES %@",
                                    "([-.]*\\s*[-.]*\\p{Arabic}*[-.]*\\s*)*[-.]*")
        return predicate.evaluate(with: self)
    }

}

and you can use like this:

print("yourString".isPersian) //response: true or false

The main key is using regex and predicate. these links help you to manipulate whatever you want:

https://nshipster.com/nspredicate/

https://nspredicate.xyz/

http://userguide.icu-project.org/strings/regexp

Feel free and ask whatever question about this topic :D

[EDIT] The following regex can be used to accept Latin numerics, as they are mostly accepted in Persian texts

"([-.]*\\s*[-.]*\\p{Arabic}*[0-9]*[-.]*\\s*)*[-.]*"

Upvotes: 2

ares777
ares777

Reputation: 3628

Based on this extension found elsewhere:

       extension String {
           func matches(_ regex: String) -> Bool {
           return self.range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil
           }
        }

and construct your regex containing allowed characters like

    let mystra = "چهار راه"
    let mystrb = "خیابان."
    let mystrc = "خیابان 5"
    let mystrd = "چرا copy کردی؟"      //and so on
    for a in mystra {
        if String(a).matches("[\u{600}-\u{6FF}\u{064b}\u{064d}\u{064c}\u{064e}\u{064f}\u{0650}\u{0651}\u{0020}]") {  // add unicode for dot, comma, and other needed puctuation marks, for now I added space etc

    } else {         // not in range
        print("oh no--\(a)---zzzz")
        break        // or return false 
        }
    }

Make sure you construct the Unicode needed using the above model. Result for other strings for a in mystrb ... etc oh no--.---zzzz oh no--5---zzzz oh no--c---zzzz

Enjoy

Upvotes: 3

Related Questions