0

Is it possible to have a string for example:

var myText = "AB12CDE"

and then check to see if 3rd and 4th letters are numbers and if not change it to a number.

So if the above text ended up being:

"ABIZCDE" 

I would be able to change IZ to 12 but not replacing all instances of I and Z but only in the 3rd and 4th charecther.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Tony Merritt
  • 1,177
  • 11
  • 35

6 Answers6

1

Here is it:

let str = "ABCIZCDEZ"
var newString = ""
var index = 0
str.forEach { (char) in            
    var charToAppend = char
    if index == 3 || index == 4 {
        if char == "Z" {
            charToAppend = "2"
        }
        if char == "I" {
            charToAppend = "1"
        }
    }
    newString.append(charToAppend)
    index += 1
}

print(newString) // ABC12CDEZ

For insertion for example you could make an extension:

Add this somewhere before your class:

public extension String {
    public func insert(string: String, index: Int) -> String {
        return String(self.prefix(index)) + string + String(self.suffix(self.count - index))
    }
}

Then:

let str2 = "ABC2CDEZ"
var newString = str2.insert(string: "I", index: 3)
print(newString) // ABCI2CDEZ
Eridana
  • 2,418
  • 23
  • 26
  • Hi thank you for this reply it makes sence and I am working it into my code. A quick question. Would the if indext == 3 || Index == 4 would that be index 2 and 3 because would it start at 0? – Tony Merritt Feb 22 '18 at 16:01
  • sorry i see that would be right because of the text you declared as str – Tony Merritt Feb 22 '18 at 16:02
  • I think this answer seems to work best for me in my limited understanding and how I am coding. Can I ask also this is replacing the charecter at that index, is there a way to also Insert rather than replace so say id it was 12 but cam back as only 2 i could insert 1 in the position and push the rest along? – Tony Merritt Feb 22 '18 at 16:21
  • @TonyMerritt, I updated my answer, hope this will help :) – Eridana Feb 23 '18 at 07:56
0

You can try something like this:

First, find the substring of your string from the range starting at location 2 and to next 2 points then check if that's an Integer. if it does not then replace it by integers.

var myText = "ABIZCDE"

        let myNSString = myText as NSString
        let subString = myNSString.substring(with: NSRange(location: 2, length: 2))

        print(subString)

        let isInt = Int(subString) != nil
        if !isInt {
            myNSString.replacingCharacters(in: NSRange(location: 2, length: 2), with: "12")
        }

        print(myNSString)

Hope it helps!!

Agent Smith
  • 2,873
  • 17
  • 32
  • This should only take care of the first occurence of `12`. Seems like OP would like to control the range of the characters to replace. – justintime Feb 22 '18 at 15:40
  • Yes, sorry it may be not fully understandable, more than likely the 3rd and 4th charecters are the only ones that will be numbers, so i need a check that is specific to the 3rd and 4th charecter to check if it is actualy a number and if not i need to be able to insert a number into it. At that position – Tony Merritt Feb 22 '18 at 15:46
  • @TonyMerritt Changed the answer.Please check! – Agent Smith Feb 22 '18 at 16:00
0

There are probably simpler alternatives but the following will work:

let myText = "ABIZCDEIZIZ"

let result = myText
    // replace any I at 3rd or 4th position with 1
    .replacingOccurrences(of: "(?<=^.{2,3})I", with: "1", options: .regularExpression)
    // replace any Z at 3rd or 4th position with 2
    .replacingOccurrences(of: "(?<=^.{2,3})Z", with: "2", options: .regularExpression)
print(result) // AB12CDEIZIZ

or, without regular expressions:

let result = String(myText.enumerated().map {
    guard (2...3).contains($0.offset) else { return $0.element }

    switch $0.element {
    case "I":
        return "1"
    case "Z":
        return "2"
    default:
        return $0.element
    }
})

print(result)

or moving the logic together:

let result = String(myText.enumerated().map {
    switch $0.element {
    case "I" where (2...3).contains($0.offset):
        return "1"
    case "Z" where (2...3).contains($0.offset):
        return "2"
    default:
        return $0.element
    }
})
Sulthan
  • 128,090
  • 22
  • 218
  • 270
0

So I mocked up something in the playground that would have the desired effect, it has the added benefit of being able to define any number of substitution rules:

import Foundation

struct Substitution {

    var origin: String
    var result: String
    var targetIndices: [Int]
}

let subs = [
    Substitution(origin: "1", result: "I", targetIndices:[2, 3]),
    Substitution(origin: "2", result: "Z", targetIndices:[2, 3])
]

let charset = CharacterSet(charactersIn: subs.map({ $0.origin }).joined(separator: ""))

let input = "AB12CDE"

func process(_ input: String) -> String {

    var output = input

    for (index, character) in input.enumerated() {
        if let sub = subs.first(where: { $0.targetIndices.contains(index) && $0.origin == String(character) }) {
            output = (output as NSString).replacingCharacters(in: NSMakeRange(index, 1), with: sub.result)
        }
    }

    return output
}

let output = process(input)
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51
Jacob King
  • 6,025
  • 4
  • 27
  • 45
0
var str = "AB12CDE"
    let index1 = str.index (str.startIndex, offsetBy: 2)
    let index2 = str.index (str.startIndex, offsetBy: 3)
    print(str[index1],str[index2])
    if str[index1] == "1" && str[index2] == "2" {
        let newString = str.prefix(2) + "IZ" + str.dropFirst(5)
        print(newString)
    }

You can try this.

Chetan Rajagiri
  • 1,009
  • 11
  • 13
0

This enumerates an exhaustive list of characters you might want to replace with alphabets, you can add more to these:

extension Character {
    var alpabetNumber: Character? {
        switch self {
        case "I":
            return "1"
        case "Z":
            return "2"
        default:
            return nil
        }
    }
}

Function which does the job:

extension String {
    mutating func namePlate() -> String {
        var index = 0
        self.forEach { (char) in
            if index == 2 || index == 3 {
                if let replacement = char.alpabetNumber {
                    self = replace(self, index, replacement)
                }
            }
            index += 1
        }
        return self
    }
}

// Helper
func replace(_ myString: String, _ index: Int, _ newChar: Character) -> String {
    var modifiedString = String()
    for (i, char) in myString.enumerated() {
        modifiedString += String((i == index) ? newChar : char)
    }
    return modifiedString
}

Usage:

var str = "ABIZCDE"
str.namePlate() // "AB12CDE"
justintime
  • 352
  • 3
  • 11