Objective-C/Swift Regex Matching Across Multliple Lines

Objective-C/Swift regex matching across multliple lines

From your feedback, I see you just need to tell the regex engine to match a newline with a period.

Use the NSRegularExpressionOptions.DotMatchesLineSeparators option:

Allow . to match any character, including line separators.




Available in OS X v10.7 and later.

As a quicker-to-implement alternative, use an inline (?s) modifier at the beginning of the pattern:

let regexString = "(?s)var\\s+kaynaklar.*?url\\s*:\\s*\\\"([^\\\"]+)\\\"\\s*,\\s*data\\s*:\\s*'([^']+)"

See the regex demo.

How do I match any character across multiple lines in a regular expression?

It depends on the language, but there should be a modifier that you can add to the regex pattern. In PHP it is:

/(.*)<FooBar>/s

The s at the end causes the dot to match all characters including newlines.

How to extract multiline string between --- in Swift

You can use String method

func range<T>(of aString: T, options mask: String.CompareOptions = default, range searchRange: Range<String.Index>? = default, locale: Locale? = default) -> Range<String.Index>? where T : StringProtocol

and use the regex pattern to find all characters between two strings from this SO answer:

let testMe = """
---
# Metadata
title: hum
author: jecatatu
email: jecatatu@gmail.com
---
This is more text outside the yaml block
"""

let pattern = "(?s)(?<=---\n).*(?=\n---)"
if let range = testMe.range(of: pattern, options: .regularExpression) {
let text = String(testMe[range])
print(text)
}

# Metadata
title: hum
author: jecatatu
email: jecatatu@gmail.com

Objective-c NSRegularExpression doesn't match

By default, the dot . does not match a line separator.
Since the text that you want to capture spans multiple lines, you have to add the
NSRegularExpressionDotMatchesLineSeparators option:

NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:regex
options:NSRegularExpressionDotMatchesLineSeparators
error:&error];

Alternatively, add (?s) to the pattern to add the "s" flag.

Swift regex - How to extract a matching group

You can use NSRegularExpression.

var pattern = ".+T(\\d\\d):(\\d\\d).+"
var string = "2014-10-29T20:44:00"

var error: NSError? = nil

var regex = NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions.DotMatchesLineSeparators, error: &error)

var result = regex?.stringByReplacingMatchesInString(string, options: nil, range: NSRange(location:0,
length:countElements(string)), withTemplate: "$1$2")

I would be inclined to do this without regular expressions, though:

var charSet = NSCharacterSet(charactersInString: "T:") 

var array =
string.componentsSeparatedByCharactersInSet(charSet)

var result2 =
"\(array[1])\(array[2])"

This breaks the datetime string to array of substrings separated by either T or : and I get the hours and minutes in second and third element of the returned array.

Re make multiple line to paragraph in objective c

This code isn't bulletproof and additional code is needed to clean up any extraneous newline characters, but it should serve to start you off:

// Assuming your input string contains all the text, then:

NSArray *paragraphs = [input componentsSeparatedByString:@"\n\n"];
for (NSString *paragraph in paragraphs)
{
NSString *cleaned = [paragraph stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
NSLog(@"paragraph = %@", cleaned);
}

How can I find lines matched by Regex A and perform replacement of Regex B? (Swift 5.5)

You can use range(of:options) to find the regex

let range = str_Test_File.range(of: regex, options: .regularExpression)

and then replacingOccurrences(of:with:options:range) to perform the replacement

replacingOccurrences(of: #"\barujabura\b"#, with: replacement, options: .regularExpression, range: range)

So the full code would be

let str_Test_File = "Algebra 0 arujabura\nAlgebra 0 daishu\nGeometry 0 jiometori\nGeometry 0 jihe\nPhysics 0 fijikusu\nPhysics 0 wuli"

let regex = #"^.*Algebra.*\b(arujabura)\b.*$"#
let replacement = "アルジャブラ"
let range = str_Test_File.range(of: regex, options: .regularExpression)

let result = str_Test_File.replacingOccurrences(of: #"\barujabura\b"#,
with: replacement,
options: .regularExpression,
range: range)

I am not quite sure why you need to make this into a two step process so as an alternative maybe you directly could do

let result = str_Test_File.replacingOccurrences(of: #"\barujabura\b"#,
with: replacement,
options: .regularExpression)

At least for the given test string the end result is the same between the two solutions.


Update

If you want to create a loop to go through and replace all matches individually I would use a while loop like this

var searchRange = strClusterTest.startIndex..<strClusterTest.endIndex
while let range = strClusterTest.range(of: regLineMatch,
options: .regularExpression,
range: searchRange) {

strClusterTest = strClusterTest.replacingOccurrences(of: replaceOf,
with: replaceWith,
options: .regularExpression,
range: range)
searchRange = range.upperBound..<strClusterTest.endIndex
}

The searchRange variable is used to only search the part of the string after the last match and the loop will exit when range(of:) returns nil. Also I believe the search regex can be changed to

let regLineMatch = #"\n?.*Algebra.*\b(daishu)\b.*\n"#


Related Topics



Leave a reply



Submit