[解決済み】Swiftで正規表現にマッチしたものを取り出す
質問
文字列から正規表現にマッチする部分文字列を抽出したい。
そこで、次のようなものを探しています。
func matchesForRegexInText(regex: String!, text: String!) -> [String] {
???
}
というわけで、こんな感じです。
func matchesForRegexInText(regex: String!, text: String!) -> [String] {
var regex = NSRegularExpression(pattern: regex,
options: nil, error: nil)
var results = regex.matchesInString(text,
options: nil, range: NSMakeRange(0, countElements(text)))
as Array<NSTextCheckingResult>
/// ???
return ...
}
問題は、その
matchesInString
の配列が渡されます。
NSTextCheckingResult
ここで
NSTextCheckingResult.range
は、型
NSRange
.
NSRange
とは互換性がありません。
Range<String.Index>
を使用することができません。
text.substringWithRange(...)
この単純なことを、何行もコードを書くことなく、swift で実現する方法をご存知ですか?
どのように解決するのですか?
たとえ
matchesInString()
メソッドは
String
を第一引数にとります。
で内部的に動作します。
NSString
を指定する必要があり、range パラメータを指定する必要があります。
を使用して
NSString
の長さではなく、Swift の文字列の長さとして扱われます。そうでない場合は
フラグのような拡張書記素クラスタでは失敗します。
現在
スウィフト4
(Xcode 9) では、Swift 標準の
との間で変換する関数を提供しています。
Range<String.Index>
と
NSRange
.
func matches(for regex: String, in text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex)
let results = regex.matches(in: text,
range: NSRange(text.startIndex..., in: text))
return results.map {
String(text[Range($0.range, in: text)!])
}
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
例
let string = "????????€4€9"
let matched = matches(for: "[0-9]", in: string)
print(matched)
// ["4", "9"]
注
強制アンラップは
Range($0.range, in: text)!
は安全です。
その
NSRange
は、与えられた文字列の部分文字列を参照しています。
text
.
しかし、それを避けたいのであれば、次のようにします。
return results.flatMap {
Range($0.range, in: text).map { String(text[$0]) }
}
の代わりに
(Swift 3 以前の古い回答です)
そこで、与えられたSwiftの文字列を
NSString
を抽出し、さらに
の範囲を指定します。結果は自動的にSwiftの文字列配列に変換されます。
(Swift 1.2用のコードは編集履歴にあります)
Swift 2 (Xcode 7.3.1) :
func matchesForRegexInText(regex: String, text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex, options: [])
let nsString = text as NSString
let results = regex.matchesInString(text,
options: [], range: NSMakeRange(0, nsString.length))
return results.map { nsString.substringWithRange($0.range)}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
例
let string = "????????€4€9"
let matches = matchesForRegexInText("[0-9]", text: string)
print(matches)
// ["4", "9"]
Swift 3 (Xcode 8)
func matches(for regex: String, in text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex)
let nsString = text as NSString
let results = regex.matches(in: text, range: NSRange(location: 0, length: nsString.length))
return results.map { nsString.substring(with: $0.range)}
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
例
let string = "????????€4€9"
let matched = matches(for: "[0-9]", in: string)
print(matched)
// ["4", "9"]
関連
-
[解決済み] キャッチできない例外 'NSInvalidArgumentException', reason: '-[_.AppDelegate add:]: unrecognized selector' により、アプリを終了する。
-
[解決済み] XHTMLの自己完結型タグを除くオープンタグにマッチするRegEx
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] 正規表現を使用した電話番号の検証方法
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] JSで文字列が正規表現にマッチするかどうかをチェックする
-
[解決済み] Bashで部分文字列を抽出する
-
[解決済み] SwiftでStringを配列に分割する?
-
[解決済み] 正規表現で部分文字列を抽出する方法
-
[解決済み】Bashでファイル名と拡張子を抽出する。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Cocoapodsをインストールできない - プロジェクト・ディレクトリにポッドファイルが見つからない
-
[解決済み] Xcode は、[バンドル ID] に一致する iOS App Store プロビジョニングプロファイルを見つけられませんでした。
-
[解決済み] Xcode 10でコマンドCompileSwiftが0以外の終了コードで失敗する [重複] 。
-
[解決済み] Xcode コマンド /usr/bin/codesign は終了コード 1 で失敗しました : errSecInternalComponent
-
[解決済み] 警告: 'characters' は非推奨です。String または Substring を直接使用してください。
-
[解決済み] Swift の performSegueWithIdentifier が動作しない。
-
[解決済み] iOS 9 : ユニバーサルアプリの警告「アプリがフルスクリーンを必要としない限り、すべてのインターフェイスの向きをサポートする必要があります」。
-
[解決済み] 'CGPointMake' は swift で使用できません [重複] 。
-
[解決済み】Swift 4でStringのsubstringを使うには?'substring(to:)'は非推奨です。部分的な範囲から'演算子を持つ文字列スライス添字を使用してください。
-
[解決済み】Swift RangeからNSRange?