First of all, Xcode can use regex for searching, whether it’s a single file Command+F or a global search. The re can be used to search for special items such as “123….” If you know the beginning and the end, but are not sure about the middle, you can use the regular 123.* ABC to search, and fade out text search can only search consecutive text.

And then Xcode can not only use regular search but also replace, which is good news!

Let’s say I have a string at sign sure, which is used all over the place, and now I need to change it to a localized mode, which is NSLocalizedString(at sign sure, nil); . Font: XXX and only used in initWithName:@” confirm “font: XXX.

Of course you can change it one place at a time, but using Xcode’s global substitution + regular subpattern can be done in one go:

In the global search options: Replace – Regular Expression, search the Regular initWithName: @ “sure”) the font, Replace the result for the initWithName: NSLocalizedString ($1, nil) the font.

You use a pair of parentheses in the re, which is a subpattern, which is when you match the re, you match not only the whole thing, but also the contents inside the parentheses, and then you get the first subpattern matched by $1. In this case, the parentheses are exactly @” sure “, so $1 is equal to @” sure “, and in the result of the substitution, $1 will be replaced with the real value.

If you have multiple parentheses, you can get them from the front to the back using the **$+ sequence **.

For example, for initWithName:@”iOS development “departmentName:@” number one title “, you need to replace the two strings in this method with localized macros, and you don’t know what the two strings are.

InitWithName :(@”.*”) departmentName:(@”.*”) initWithName:NSLocalizedString($1,nil) departmentName:NSLocalizedString($2,nil)

The final result is: initWithName: NSLocalizedString (@ “iOS development,” nil) departmentName: NSLocalizedString (@ “number one title,” nil)

The great thing about using a subpattern is that it allows you to copy parts of the original string without knowing what they are. For example, in the case above, two strings can be any value and remain the same value after modification. It’s impossible to do this with plain text substitution because it requires you to make sure you write down the value of the substitution explicitly.

In iOS development, you can also use subpatterns, like when you’re dealing with a string, you have to extract the phone number from it. Then you can observe that the phone number is of the form “xx phone number :15812345678”, and the re can be written as: phone number :[1-9]{11}.

The matching is easy, but the problem is that the matching is not the value of the phone number, but the whole string of “phone number: XXX”. You can choose from:

  1. Get the whole string and then intercept it with subString and so on
  2. Use subpattern matching

The first is more difficult if the content you want is not in a fixed location, such as “phone number :” with an indeterminate space between the phone number.

How to use submodes in iOS?

Regular uses the NSRegularExpression class, which uses methods like matchesInString: Options: range: to get an array of NSTExtCheckingResults.

Each NSTextCheckingResult represents a regular match, and then entering the class, you can see that there are two methods:

/* A result must have at least one range, but may optionally have more (for example, to represent regular expression capture groups).  The range at index 0 always matches the range property.  Additional ranges, if any, will have indexes from 1 to numberOfRanges-1. */
@property (readonly) NSUInteger numberOfRanges NS_AVAILABLE(10_7, 4_0);
- (NSRange)rangeAtIndex:(NSUInteger)idx NS_AVAILABLE(10_7, 4_0);
Copy the code

So this is how you get the result of the subpattern match, numberOfRanges indicates that there are several ranges, the first range is the entire range of the regular match, and then numberOfRanges up to numberOfRanges is the range of the subpattern match. Use the rangeAtIndex to get the range of subpatterns.

Returning to the phone number problem above, the re should be written as the phone number []*:[]*([1-9]{11}), so that the phone number: 15811329743 and @” phone number: 14729749274″ can match.

Then take the range of submodes:

for (NSTextCheckingResult * match in matches) {
	if([match numberOfRanges] > 1){ NSString *phone = [str substringWithRange:[match rangeAtIndex:1]]; }}Copy the code

This way, you can handle all kinds of strange changes and get the value you want directly!