5

I have string:

Simple text   with    spaces

I need regular expression which select:

  • leading
  • trailing
  • more than 1 space

Example:

_ - space

_Simple text __with ___spaces_
Artem Krachulov
  • 557
  • 6
  • 23

6 Answers6

5

My 2ct:

let text = "    Simple text   with    spaces    "
let pattern = "^\\s+|\\s+$|\\s+(?=\\s)"
let trimmed = text.stringByReplacingOccurrencesOfString(pattern, withString: "", options: .RegularExpressionSearch)
println(">\(trimmed)<") // >Simple text with spaces<

^\s+ and \s+$ match one or more white space characters at the start/end of the string.

The tricky part is the \s+(?=\s) pattern, which matches one or more white space characters followed by another white space character which itself is not considered part of the match (a "look-ahead assertion").

Generally, \s matches all white-space characters such as the space character itself, horizontal tabulation, newline, carriage-return, linefeed or formfeed. If you want to remove only the (repeated) space characters then replace the pattern by

let pattern = "^ +| +$| +(?= )"
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Be interesting to know if this outperforms the two-step for various possible strings, given the more complex regex is probably slower. – Airspeed Velocity May 21 '15 at 14:02
  • Just a note: the regex `\s` matches a space, a tab, a line break, or a form feed. If you only want to match spaces us an actual space – Robert Smit May 21 '15 at 14:16
  • @AirspeedVelocity: No significant difference. For 1MB text: Your method: 0.572 seconds, my method 0.502 seconds. – Martin R May 21 '15 at 18:01
3

You can keep the regular expression simple by doing the leading/trailing part as a second stage:

 let singlySpaced = " Simple text   with    spaces   "
      .stringByReplacingOccurrencesOfString("\\s+", withString: " ", options: .RegularExpressionSearch)
      .stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

(assuming you want to strip all kinds of whitespace – you can adjust it down to just do only spaces fairly easily)

There are more complex regexprs that will do it in one shot, but personally I prefer the two-step version over obfuscation (and as @MartinR mentions, performance is very similar between the two, given a trim is a very lightweight operation vs a slower more-complex regex - so it’s really down to which you prefer the look of).

Airspeed Velocity
  • 40,491
  • 8
  • 113
  • 118
  • Maybe exist way to use only stringByReplacingOccurrencesOfString method. Example: let singlySpaced = " Simple text with spaces ".stringByReplacingOccurrencesOfString("REGULAR EXPRESSION", withString: "", options: .RegularExpressionSearch). REGULAR EXPRESSION will select leading, trailing and more than 1 space? P.S. I need save perform time. – Artem Krachulov May 21 '15 at 12:40
  • It’s easy to match leading/trailing/more than one thing at once (as Robert’s answer shows) with `^ | +| $`. The tricky part is what to replace it with if you want to strip – you want to replace leading/trailing with nothing, but replace multiple internal spaces with a single space. – Airspeed Velocity May 21 '15 at 12:47
1

This ought to clean your strings up:

var string : NSString = "  hello    world.  "
while string.rangeOfString("  ").location != NSNotFound { //note the use of two spaces
    string = string.stringByReplacingOccurrencesOfString("  ", withString: " ")
}
println(string)
string = string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
println(string)
Danny Bravo
  • 4,534
  • 1
  • 25
  • 43
1

Some good answers have been provided, but if you want a regex the following should work:

^ |(?<= ) +| $

The | indicates alternatives, the ^ is the beginning of a string, the $ indicates the end of the string. So this matches beginning of the string followed by a space OR one or more spaces preceded by a space OR a space at the end of the string.

Robert Smit
  • 118
  • 6
0

Following will remove all the spaces

NSString *spaces =@"hi how are you "; 

NSString *withoutSpace= [spaces stringByReplacingOccurrencesOfString:@"  " 
                               withString:@" "];
withoutSpace = [withoutSpace stringByTrimmingCharactersInSet:
                              [NSCharacterSet whitespaceCharacterSet]];
MOHAMMAD ISHAQ
  • 988
  • 7
  • 15
  • This will work for removing all spaces but I believe he wants to leave some spaces behind. It appears that he wants to leave 1 space between words. –  May 21 '15 at 12:29
  • sorry please check updated answer ...he wants to remove ,trailing , leading and more than one , this will do the same – MOHAMMAD ISHAQ May 21 '15 at 12:34
  • Yep, that'll do it! The other thing is that the language listed in the question is Swift, your code is Objective-C. Not that hard to convert but it's still a mismatch. –  May 21 '15 at 12:48
  • Perhaps not, I didn't downvote it so that's up to whoever did. –  May 21 '15 at 12:51
-1

this function will leave one space between words

let accountNameStr = "   test    test   "
    let trimmed = accountNameStr.replacingOccurrences(of: "\\s+", with: " ", options: .regularExpression)
    let textWithoutSpace = trimmed.trimmingCharacters(in: .whitespaces)

Output : test test