5

i was looking for an answer but haven't found one yet, so:

For example: i have a string like "#blablub" and i want to remove the # at the beginning, i can just simply remove the first char. But, if i have a string with "#####bla#blub" and i only want to remove all # only at the beginning of the first string, i have no idea how to solve that.

My goal is to get a string like this "bla#blub", otherwise it would be to easy with replaceOccourencies...

I hope you can help.

Fry
  • 922
  • 2
  • 10
  • 24
  • Use a loop while the first char is the one you wish to delete. – rmaddy Sep 15 '16 at 15:04
  • 1
    You can use a regular expression search as for example in http://stackoverflow.com/a/28958785/1187415. – Martin R Sep 15 '16 at 15:07
  • @MartinR http://programmers.stackexchange.com/questions/223634/what-is-meant-by-now-you-have-two-problems :) – rmaddy Sep 15 '16 at 15:13
  • 2
    `string.replacingOccurrences(of: "^\\#*", with: "", options: .regularExpression)` looks simple enough to me, and does not create a sequence of intermediate strings. – Martin R Sep 15 '16 at 15:22

6 Answers6

7

Swift2

func ltrim(str: String, _ chars: Set<Character>) -> String {
    if let index = str.characters.indexOf({!chars.contains($0)}) {
        return str[index..<str.endIndex]
    } else {
        return ""
    }
}

Swift3

func ltrim(_ str: String, _ chars: Set<Character>) -> String {
    if let index = str.characters.index(where: {!chars.contains($0)}) {
        return str[index..<str.endIndex]
    } else {
        return ""
    }
}

Usage:

ltrim("#####bla#blub", ["#"]) //->"bla#blub"
OOPer
  • 47,149
  • 6
  • 107
  • 142
6
var str = "###abc"

while str.hasPrefix("#") {
    str.remove(at: str.startIndex)
}

print(str)
wint
  • 1,266
  • 2
  • 14
  • 28
3

I recently built an extension to String that will "clean" a string from the start, end, or both, and allow you to specify a set of characters which you'd like to get rid of. Note that this will not remove characters from the interior of the String, but it would be relatively straightforward to extend it to do that. (NB built using Swift 2)

enum stringPosition {
    case start
    case end
    case all
}

    func trimCharacters(charactersToTrim: Set<Character>, usingStringPosition: stringPosition) -> String {
        // Trims any characters in the specified set from the start, end or both ends of the string
        guard self != "" else { return self } // Nothing to do
        var outputString : String = self

        if usingStringPosition == .end || usingStringPosition == .all {
            // Remove the characters from the end of the string
            while outputString.characters.last != nil && charactersToTrim.contains(outputString.characters.last!) {
                outputString.removeAtIndex(outputString.endIndex.advancedBy(-1))
            }
        }

        if usingStringPosition == .start || usingStringPosition == .all {
            // Remove the characters from the start of the string
            while outputString.characters.first != nil && charactersToTrim.contains(outputString.characters.first!) {
                outputString.removeAtIndex(outputString.startIndex)
            }
        }

        return outputString
    }
Marcus
  • 2,153
  • 2
  • 13
  • 21
0

A regex-less solution would be:

func removePrecedingPoundSigns(s: String) -> String {
    for (index, char) in s.characters.enumerate() {
        if char != "#" {
            return s.substringFromIndex(s.startIndex.advancedBy(index))
        }
    }
    return ""
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
0

A swift 3 extension starting from OOPer's response:

extension String {
    func leftTrim(_ chars: Set<Character>) -> String {
        if let index = self.characters.index(where: {!chars.contains($0)}) {
            return self[index..<self.endIndex]
        } else {
            return ""
        }
    }
}
Ciprian Rarau
  • 3,040
  • 1
  • 30
  • 27
0

As Martin R already pointed out in a comment above, a regular expression is appropriate here:

myString.replacingOccurrences(of: #"^#+"#, with: "", options: .regularExpression)

You can replace the inner # with any symbol you're looking for, or you can get more complicated if you're looking for one of several characters or a group etc. The ^ indicates it's the start of the string (so you don't get matches for # symbols in the middle of the string) and the + represents "1 or more of the preceding character". (* is 0 or more but there's not much point in using that here.)

Note the outer hash symbols are to turn the string into a raw String so escaping is not needed (though I suppose there's nothing that actually needs to be escaped in this particular example).

To play around with regex I recommend: https://regexr.com/

shim
  • 9,289
  • 12
  • 69
  • 108