Created
May 18, 2021 17:10
-
-
Save ralbertini/1ea87febc2fa029dcd2c0819af3bbabb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Mask.swift | |
import Foundation | |
public extension String { | |
fileprivate static let anyoneCharUpper = "X" | |
fileprivate static let onlyCharUpper = "C" | |
fileprivate static let onlyNumberUpper = "N" | |
fileprivate static let anyoneChar = "x" | |
fileprivate static let onlyChar = "c" | |
fileprivate static let onlyNumber = "n" | |
//swiftlint:disable function_parameter_count | |
fileprivate func verifyCharFormater(_ charFormatString: String, | |
_ stringToAdd: inout String, | |
_ charString: String, | |
_ counter: inout Int, | |
_ charStringUpper: String, | |
_ charFormatStringUpper: String) { | |
if charFormatString == String.anyoneChar { | |
stringToAdd = charString | |
counter += 1 | |
} else if charFormatString == String.anyoneCharUpper { | |
stringToAdd = charStringUpper | |
counter += 1 | |
} else if charFormatString == String.onlyCharUpper { | |
counter += 1 | |
if charStringUpper.isChar() { | |
stringToAdd = charStringUpper | |
} | |
} else if charFormatString == String.onlyChar { | |
counter += 1 | |
if charString.isChar() { | |
stringToAdd = charString | |
} | |
} else if charFormatStringUpper == String.onlyNumberUpper { | |
counter += 1 | |
if charString.isNumber() { | |
stringToAdd = charString | |
} | |
} else { | |
stringToAdd = charFormatString | |
} | |
} | |
fileprivate func addStringFormat(_ format: String, | |
_ stringUnformated: String, | |
_ counter: inout Int, | |
_ newString: inout String) { | |
for i in 0..<format.count { | |
var stringToAdd = "" | |
let unicharFormatString = format[i] | |
let charFormatString = unicharFormatString | |
let charFormatStringUpper = unicharFormatString.uppercased() | |
let unicharString = stringUnformated[counter] | |
let charString = unicharString | |
let charStringUpper = unicharString.uppercased() | |
verifyCharFormater(charFormatString, | |
&stringToAdd, | |
charString, | |
&counter, | |
charStringUpper, | |
charFormatStringUpper) | |
newString += stringToAdd | |
if counter == stringUnformated.count, i == format.count - 2 { | |
let lastUnicharFormatString = format[i + 1] | |
let lastCharFormatStringUpper = lastUnicharFormatString.uppercased() | |
if lastCharFormatStringUpper != String.onlyCharUpper && | |
lastCharFormatStringUpper != String.onlyNumberUpper && | |
lastCharFormatStringUpper != String.anyoneCharUpper { | |
newString += lastUnicharFormatString | |
} | |
break | |
} | |
} | |
} | |
func format(_ format: String, oldString: String) -> String { | |
let stringUnformated = self.unformat(format, oldString: oldString) | |
var newString = String() | |
var counter = 0 | |
if stringUnformated.count == counter { | |
return newString | |
} | |
addStringFormat(format, stringUnformated, &counter, &newString) | |
return newString | |
} | |
fileprivate func changeIndexofChar(_ string: String, _ oldString: String, _ changeCharIndex: inout Int) { | |
for i in 0..<string.count { | |
let unicharString = string[i] | |
let charString = unicharString | |
let unicharString2 = oldString[i] | |
let charString2 = unicharString2 | |
if charString != charString2 { | |
changeCharIndex = i | |
break | |
} | |
} | |
} | |
fileprivate func findCharString(_ i: inout Int, | |
_ oldString: String, | |
_ undefineChars: [String], | |
_ string: inout String) { | |
while i >= 0 { | |
let findUnicharString = oldString[i] | |
let findCharString = findUnicharString | |
var control2 = false | |
for undefineChar in undefineChars where undefineChar == findCharString { | |
control2 = true | |
} | |
if !control2 { | |
string = (oldString as NSString).replacingCharacters(in: NSRange(location: i, length: 1), with: "") | |
break | |
} | |
i -= 1 | |
} | |
} | |
fileprivate func removeStringFormat(_ oldString: String, _ string: inout String, _ undefineChars: [String]) { | |
if oldString.count - 1 == string.count { | |
var changeCharIndex = 0 | |
changeIndexofChar(string, oldString, &changeCharIndex) | |
let changedUnicharString = oldString[changeCharIndex] | |
let changedCharString = changedUnicharString | |
var control = false | |
for undefineChar in undefineChars where undefineChar == changedCharString { | |
control = true | |
} | |
if control { | |
var i = changeCharIndex - 1 | |
findCharString(&i, oldString, undefineChars, &string) | |
} | |
} | |
} | |
fileprivate func verifyUnformatChar(_ charFormatStringUpper: String, | |
_ charFormatString: String, | |
_ undefineChars: inout [String]) { | |
if charFormatStringUpper != String.anyoneCharUpper && | |
charFormatStringUpper != String.onlyCharUpper && | |
charFormatStringUpper != String.onlyNumberUpper { | |
var control = false | |
for undefineChar in undefineChars where undefineChar == charFormatString { | |
control = true | |
} | |
if !control { | |
undefineChars.append(charFormatString) | |
} | |
} | |
} | |
func unformat(_ format: String, oldString: String) -> String { | |
var string: String = self | |
var undefineChars = [String]() | |
for i in 0..<format.count { | |
let unicharFormatString = format[i] | |
let charFormatString = unicharFormatString | |
let charFormatStringUpper = unicharFormatString.uppercased() | |
verifyUnformatChar(charFormatStringUpper, charFormatString, &undefineChars) | |
} | |
removeStringFormat(oldString, &string, undefineChars) | |
for i in 0..<undefineChars.count { | |
string = string.replacingOccurrences(of: undefineChars[i], with: "") | |
} | |
return string | |
} | |
fileprivate func isChar() -> Bool { | |
return self.regexControlString(pattern: "[a-zA-ZğüşöçıİĞÜŞÖÇ]") | |
} | |
fileprivate func isNumber() -> Bool { | |
return self.regexControlString(pattern: "^[0-9]*$") | |
} | |
fileprivate func regexControlString(pattern: String) -> Bool { | |
do { | |
let regex = try NSRegularExpression(pattern: pattern, options: []) | |
let numberOfMatches = regex.numberOfMatches(in: self, | |
options: [], | |
range: NSRange(location: 0, length: self.count)) | |
return numberOfMatches == self.count | |
} catch { | |
return false | |
} | |
} | |
} | |
public extension String { | |
fileprivate subscript(i: Int) -> String { | |
guard i >= 0 && i < count else { | |
return "" | |
} | |
return String(self[index(startIndex, offsetBy: i)]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment