Issue #698

Xcode has powerful search. We can constrain search to be scoped in workspace, project or some folders. We can also constrain case sensitivity.

Another cool thing that people tend to overlook is, besides searching based on text, we can search based on references, definitions, call hierarchy, and πŸŽ‰ regular expressions.

Searching for regular expression gives us extra power when it comes to limit our search based on some criteria. For example when we are about to refactor some NSLayoutAnchor code and we want to find all NSLayoutConstraint. calls that stops at bottomAnchor

Here ’s how to search NSLayoutConstraint calls that involves bottomAnchor

(NSLayoutConstraint(.*[\r\n])*).+?(?=bottomAnchor)
NSLayoutConstraint.activate([
    child.leadingAnchor.constraint(equalTo: parent.safeAreaLayoutGuide.leadingAnchor),
    child.trailingAnchor.constraint(equalTo: parent.safeAreaLayoutGuide.trailingAnchor),
    child.topAnchor.constraint(equalTo: parent.safeAreaLayoutGuide.topAnchor),
    child.bottomAnchor.constraint(equalTo: parent.safeAreaLayoutGuide.bottomAnchor)
])

Another tip when searching for regular expression is that we can use https://regex101.com/ to validate and fine tune our regex. Below are breakdowns of our regex. Note how we use /.+?(?=abc)/ to define “search until”

/
(NSLayoutConstraint(.*[\r\n])*).+?(?=bottomAnchor)
/
gm
1st Capturing Group (NSLayoutConstraint(.*[\r\n])*)
NSLayoutConstraint matches the characters NSLayoutConstraint literally (case sensitive)
2nd Capturing Group (.*[\r\n])*
* Quantifier β€” Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
A repeated capturing group will only capture the last iteration. Put a capturing group around the repeated group to capture all iterations or use a non-capturing group instead if you're not interested in the data
.* matches any character (except for line terminators)
* Quantifier β€” Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
Match a single character present in the list below [\r\n]
\r matches a carriage return (ASCII 13)
\n matches a line-feed (newline) character (ASCII 10)
.+? matches any character (except for line terminators)
+? Quantifier β€” Matches between one and unlimited times, as few times as possible, expanding as needed (lazy)
Positive Lookahead (?=bottomAnchor)
Assert that the Regex below matches
bottomAnchor matches the characters bottomAnchor literally (case sensitive)
Global pattern flags
g modifier: global. All matches (don't return after first match)
m modifier: multi line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)