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 theNSRegularExpressionDotMatchesLineSeparators
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
Check Browser CSS Property Support with JavaScript
Leaflet Map Not Displayed Properly Inside Tabbed Panel
How to Access the Value of Invalid/Custom CSS Properties from JavaScript
Read CSS Property of an Element Using JavaScript
What Chars Needs Escaping in Queryselector
How to Compare Two Color Values in Jquery/Javascript
Add a Transform Value to the Current Transforms That Are Already on the Element
Jquery Event That Triggers After CSS Is Loaded
Limit Labels Number on Chart.Js Line Chart
Resetting the Opacity of a Child Element - Maple Browser (Samsung Tv App)
Change CSS Properties on Click
How to Make Changeable Themes Using CSS and JavaScript
Find by Key Deep in a Nested Array
Sign PDF with Plain JavaScript
State Not Updating When Using React State Hook Within Setinterval