# Regular Expressions Tutorial: Getting Started | Ray Wenderlich

**URL:** <https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837>\
**Category:** 🎓 Courses & Articles\
**Created:** [September 10, 2018, 2:45pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837 "2018-09-10T14:45:10Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomelliott](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/tomelliott/32/109383_2.png) [@tomelliott](https://forums.kodeco.com/u/tomelliott)\
**Post date:** [September 10, 2018, 2:45pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/1 "2018-09-10T14:45:10Z")

</div>

This introduction to regular expressions teaches you the basics of regular expressions and how to use them.

* * *
This is a companion discussion topic for the original entry at [https://www.raywenderlich.com/5765-regular-expressions-tutorial-getting-started](https://www.raywenderlich.com/5765-regular-expressions-tutorial-getting-started)

---

<div class="post-metadata">

**Author:** ![aleroy](https://s3.amazonaws.com/cdn.raywenderlich.com/community/forum-assets/noun-game-ghost-878668.png) [@aleroy](https://forums.kodeco.com/u/aleroy)\
**Post date:** [September 14, 2018, 4:01pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/2 "2018-09-14T16:01:25Z")

</div>

The starter project would not compile out of the box.  
XCode 9.4.1  
macOS 10.13.6 (High Sierra)

Here’s a diff that made it happy:

```
--- [SOURCE ROOT]/iRegex/iRegex_StarterProject/iRegex/LoginViewController.swift
+++ [SOURCE ROOT]/iRegex/iRegex_StarterProject/iRegex/LoginViewController.swift
@@ -42,8 +42,8 @@

override func viewDidLoad() {
let notificationCenter = NotificationCenter.default
- notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
- notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
+ notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: .UIKeyboardWillHide, object: nil)
+ notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: .UIKeyboardWillChangeFrame, object: nil)

passwordField.becomeFirstResponder()

@@ -65,10 +65,10 @@
@objc func adjustForKeyboard(notification: Notification) {
let userInfo = notification.userInfo!

- let keyboardScreenEndFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
+ let keyboardScreenEndFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)

- if notification.name == UIResponder.keyboardWillHideNotification {
+ if notification.name == Notification.Name.UIKeyboardWillHide {
scrollView.contentInset = .zero
} else {
scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height + 72, right: 0)

--- [SOURCE ROOT]/iRegex/iRegex_StarterProject/iRegex/SearchViewController.swift
+++ [SOUCE ROOT]/iRegex/iRegex_StarterProject/iRegex/SearchViewController.swift
@@ -122,7 +122,7 @@
let attributedText = textView.attributedText.mutableCopy() as! NSMutableAttributedString
for match in matches {
let matchRange = match.range
- attributedText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.blue, range: matchRange)
+ attributedText.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.blue, range: matchRange)
}
textView.attributedText = (attributedText.copy() as! NSAttributedString)
}
@@ -132,7 +132,7 @@

for match in matches {
let matchRange = match.range
- attributedText.removeAttribute(NSAttributedString.Key.foregroundColor, range: matchRange)
+ attributedText.removeAttribute(NSAttributedStringKey.foregroundColor, range: matchRange)
}
textView.attributedText = (attributedText.copy() as! NSAttributedString)
}

```

---

<div class="post-metadata">

**Author:** ![aleroy](https://s3.amazonaws.com/cdn.raywenderlich.com/community/forum-assets/noun-game-ghost-878668.png) [@aleroy](https://forums.kodeco.com/u/aleroy)\
**Post date:** [September 14, 2018, 4:31pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/3 "2018-09-14T16:31:46Z")

</div>

…or get XCode 10 🤔🤯

---

<div class="post-metadata">

**Author:** ![tomelliott](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/tomelliott/32/109383_2.png) [@tomelliott](https://forums.kodeco.com/u/tomelliott)\
**Post date:** [September 19, 2018, 12:19pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/4 "2018-09-19T12:19:04Z")

</div>

Thanks for adding this, hopefully it’ll be useful for others :]

---

<div class="post-metadata">

**Author:** ![nunop](https://s3.amazonaws.com/cdn.raywenderlich.com/community/forum-assets/noun-game-ghost-878668.png) [@nunop](https://forums.kodeco.com/u/nunop)\
**Post date:** [November 20, 2018, 11:36am UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/5 "2018-11-20T11:36:23Z")

</div>

Hi! The documentation at [Apple Developer Documentation](https://developer.apple.com/documentation/foundation/nsregularexpression)  
mentions that the flag values (options) may be specified within the pattern using the `(?ismx-ismx)` pattern options.  
I could not find an example of how to write these options in the pattern instead of using the **options** parameter.  
How does one write the flags into the pattern?

---

<div class="post-metadata">

**Author:** ![shogunkaramazov](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shogunkaramazov/32/108826_2.png) [@shogunkaramazov](https://forums.kodeco.com/u/shogunkaramazov)\
**Post date:** [December 12, 2018, 2:44am UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/6 "2018-12-12T02:44:32Z")

</div>

@tomelliott Can you please help with this when you get a chance? Thank you - much appreciated! :]

---

<div class="post-metadata">

**Author:** ![tomelliott](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/tomelliott/32/109383_2.png) [@tomelliott](https://forums.kodeco.com/u/tomelliott)\
**Post date:** [December 13, 2018, 8:59pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/7 "2018-12-13T20:59:03Z")

</div>

Hi @nunop, you specify the ismwx options within parenthesis, like this:

```
"Hello (?i)world" 

```

In this instance, even if your regular expression didn’t have the `NSRegularExpression.Options.caseInsensitive` option set, “world” would be matched with any capitalisation.

Here’s some example code you can copy into a Playground:

```
import Foundation

// Here, we have a regular expression which is case sensitive. Consequently we match only the final, all lowercase hello and the final, all lowercase world, for 2 total matches
if let regex = try? NSRegularExpression(pattern: "hello|world", options: []) {
  let haystack = "Hello HELLO hello World WORLD world"
  let range = NSMakeRange(0, haystack.count)
  let matches = regex.matches(in: haystack, options: [], range: range)

  print("Found \(matches.count) match(es)")
} else {
  print("Invalid pattern")
}

// Here, we have the same pattern, but we've made the entire thing case insensitive, so we match all three hellos and all three worlds, for 6 total matches.
if let regex = try? NSRegularExpression(pattern: "hello|world", options: [.caseInsensitive]) {
  let haystack = "Hello HELLO hello World WORLD world"
  let range = NSMakeRange(0, haystack.count)
  let matches = regex.matches(in: haystack, options: [], range: range)

  print("Found \(matches.count) match(es)")
} else {
  print("Invalid pattern")
}

// Finally, we have the same pattern but using the ?ismwx flags, which apply to only a part of a pattern. So in this case, we set the second part of the pattern to be case insensitive matching world with any case, but keep hello case sensitive, for 4 total matches
if let regex = try? NSRegularExpression(pattern: "hello|(?i)world", options: []) {
  let haystack = "Hello HELLO hello World WORLD world"
  let range = NSMakeRange(0, haystack.count)
  let matches = regex.matches(in: haystack, options: [], range: range)

  print("Found \(matches.count) match(es)")
} else {
  print("Invalid pattern")
}

```

---

<div class="post-metadata">

**Author:** ![magnas](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/magnas/32/105896_2.png) [@magnas](https://forums.kodeco.com/u/magnas)\
**Post date:** [December 21, 2018, 9:55am UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/8 "2018-12-21T09:55:15Z")

</div>

I’ve just implemented the first part of the tutorial where I can search for text and see any matches highlighted in yellow. I searched for **eee** and expected all the e’s in **eeeeeeee** vil to be highlighted but only the first six are, i.e. **eeeeee** eevil. I don’t understand why the last highlighted e along with the two unhighlighted e’s aren’t a match as well. All the e’s are highlighted if I search for **ee** or **eeee**.

---

<div class="post-metadata">

**Author:** ![tomelliott](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/tomelliott/32/109383_2.png) [@tomelliott](https://forums.kodeco.com/u/tomelliott)\
**Post date:** [December 27, 2018, 10:33am UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/9 "2018-12-27T10:33:16Z")

</div>

Hi @magnas. This is as expected. When the regular expression matches a range in the string the Regex engine moves on to the following character after the end of the match and _not_ the next character after the beginning of the match.

You can see this clearly using the following regex testing site (which isn’t Swift specific) , which highlights each matched range independently (or by breakpointing in Xcode and inspecting the range for each match. I added breakpoints at lines 109 and 111 in `SearchViewController`)

**2 e’s**

> **[RegExr: Learn, Build, & Test RegEx](https://regexr.com/45i0d)**
>
> RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).

(and from the debugger)

```
(lldb) po matches

▿ 14 elements

- 0 : &lt;NSSimpleRegularExpressionCheckingResult: 0x600002525780&gt;{101, 2}{&lt;NSRegularExpression: 0x600003e3b2d0&gt; ee 0x0}

- 1 : &lt;NSSimpleRegularExpressionCheckingResult: 0x600002525740&gt;{103, 2}{&lt;NSRegularExpression: 0x600003e3b2d0&gt; ee 0x0}

- 2 : &lt;NSSimpleRegularExpressionCheckingResult: 0x600002525700&gt;{105, 2}{&lt;NSRegularExpression: 0x600003e3b2d0&gt; ee 0x0}

- 3 : &lt;NSSimpleRegularExpressionCheckingResult: 0x600002525600&gt;{107, 2}{&lt;NSRegularExpression: 0x600003e3b2d0&gt; ee 0x0}

... (plus 10 more)

(lldb) po matchRange

▿ {101, 2}

- location : 101

- length : 2

(lldb) po matchRange

▿ {103, 2}

- location : 103

- length : 2

(lldb) po matchRange

▿ {105, 2}

- location : 105

- length : 2

(lldb) po matchRange

▿ {107, 2}

- location : 107

- length : 2

```

**3 e’s**

> **[RegExr: Learn, Build, & Test RegEx](https://regexr.com/45i07)**
>
> RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).

(and from the debbugger)

```
(lldb) po matches

▿ 2 elements

- 0 : &lt;NSSimpleRegularExpressionCheckingResult: 0x6000025532c0&gt;{101, 3}{&lt;NSRegularExpression: 0x600003e303f0&gt; eee 0x0}

- 1 : &lt;NSSimpleRegularExpressionCheckingResult: 0x600002550b80&gt;{104, 3}{&lt;NSRegularExpression: 0x600003e303f0&gt; eee 0x0}

(lldb) po matchRange

▿ {101, 3}

- location : 101

- length : 3

(lldb) po matchRange

▿ {104, 3}

- location : 104

- length : 3

```

---

<div class="post-metadata">

**Author:** ![magnas](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/magnas/32/105896_2.png) [@magnas](https://forums.kodeco.com/u/magnas)\
**Post date:** [December 27, 2018, 11:12am UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/10 "2018-12-27T11:12:07Z")

</div>

Ah now it’s clear. Many thanks, Tom.

---

<div class="post-metadata">

**Author:** ![thinh\_le](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/thinh_le/32/81494_2.png) [@thinh\_le](https://forums.kodeco.com/u/thinh_le)\
**Post date:** [January 30, 2019, 3:54pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/11 "2019-01-30T15:54:48Z")

</div>

Hi Tom, Thanks for the tutorial. Currently, in my project, I have to detect the characters outside of this set. [^a-zA-Z0-9 !@#$^&\*\_+=-~/?.:'‘’].

So far, I’m not able to include the square brackets “[” and “]” into the set. For “-” minus sign, I can using 2 “\” forward slashes.

I tried working on [regexr.com](http://regexr.com). It worked there, but when I copied to my Xcode swift program, it doesn’t.

Thanks.

Tim

---

<div class="post-metadata">

**Author:** ![shogunkaramazov](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shogunkaramazov/32/108826_2.png) [@shogunkaramazov](https://forums.kodeco.com/u/shogunkaramazov)\
**Post date:** [January 30, 2019, 4:12pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/12 "2019-01-30T16:12:57Z")

</div>

@thinh_le Please let us know what regular expression are you using exactly. Thank you!

---

<div class="post-metadata">

**Author:** ![tomelliott](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/tomelliott/32/109383_2.png) [@tomelliott](https://forums.kodeco.com/u/tomelliott)\
**Post date:** [January 30, 2019, 4:29pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/13 "2019-01-30T16:29:59Z")

</div>

Hi Tim.

Escaping square brackets is the same as escaping other reserved characters, you just need a two slashes in your pattern, like this:

`"\\["`

If that’s not working for you then you likely have a different underlying issue. As @shogunkaramazov mentions if you can provide the exact code you’re using I’ll see what I can do!

---

<div class="post-metadata">

**Author:** ![tomelliott](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/tomelliott/32/109383_2.png) [@tomelliott](https://forums.kodeco.com/u/tomelliott)\
**Post date:** [January 30, 2019, 4:54pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/14 "2019-01-30T16:54:28Z")

</div>

> [@thinh\_le](#):
>
> =-~

oh, I bet this is because you’ve not escaped the dash properly. This means the regex engine will be treating `=-~` as a character range between = (61 in ASCII) and ~ (126 in ASCII), which is basically everything you care about other than digits.

If I’ve understood correctly, use the following string as the pattern input for your regular expression and you should be all good:

`"[^a-zA-Z0-9 \\[\\]!@#$^&*_+=\\-~/?.:'\"]"`

---

<div class="post-metadata">

**Author:** ![thinh\_le](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/thinh_le/32/81494_2.png) [@thinh\_le](https://forums.kodeco.com/u/thinh_le)\
**Post date:** [January 30, 2019, 5:34pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/15 "2019-01-30T17:34:01Z")

</div>

Hi Tom, it’s working with just “\\]” . Thanks.

As for the “[”, I tried in [www.regexr.com](http://www.regexr.com), it works as is without any escape character. But when I inserted to my Swift program, it allows “[” as well as other unwanted characters. So I used “\\[” as you suggested.

As for the “=-~”, our code is actually “=\\-~”, which allows the minus sign in our set.

So, it is good like this, as I don’t need the double quote.

“[^a-zA-Z0-9 \\[\\]!@#$^&\*\_+=\\-~/?.:'()]”

Thanks Tom for the quick reply.

---

<div class="post-metadata">

**Author:** ![thinh\_le](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/thinh_le/32/81494_2.png) [@thinh\_le](https://forums.kodeco.com/u/thinh_le)\
**Post date:** [January 30, 2019, 5:37pm UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/16 "2019-01-30T17:37:07Z")

</div>

Thanks also to Shogunkaramazov !

---

<div class="post-metadata">

**Author:** ![shogunkaramazov](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shogunkaramazov/32/108826_2.png) [@shogunkaramazov](https://forums.kodeco.com/u/shogunkaramazov)\
**Post date:** [March 25, 2019, 11:59am UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/17 "2019-03-25T11:59:42Z")

</div>

This tutorial is more than six months old so questions are no longer supported at the moment for it. Thank you!

---

<div class="post-metadata">

**Author:** ![shogunkaramazov](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/shogunkaramazov/32/108826_2.png) [@shogunkaramazov](https://forums.kodeco.com/u/shogunkaramazov)\
**Post date:** [March 25, 2019, 11:59am UTC](https://forums.kodeco.com/t/regular-expressions-tutorial-getting-started-ray-wenderlich/48837/18 "2019-03-25T11:59:44Z")

</div>

Closed on March 25, 2019, 11:59am UTC


