web-dev-qa-db-ja.com

Swift-単一の円記号を削除します

これはおそらくばかげた質問ですが、私はSwiftに不慣れで、実際にはこれを理解できません。

URLを文字列 "http:\/\/xxx"として返すAPIがあります。 APIから返されたURLをこの形式で保存する方法がわかりません。バックスラッシュのため、変数に保存できません。

From Apple doc:

...文字列にエスケープされていない円記号(\)、..を含めることはできません。

このような文字列を保存する方法、これらの単一の円記号を削除する方法、またはこれを操作する方法はありますか?

アドバイスありがとうございます。

8
marysmech

たとえば、これらの円記号を置き換えることができます。

let string2 = string1.stringByReplacingOccurrencesOfString("\\", withString: "")

ただし、可能であれば、これらのバックスラッシュを返すAPIを修正する必要があります。これは、明らかに正しくないためです。そのコードの作者は、スラッシュをエスケープする必要があるという誤った印象を受けていたようですが、これは真実ではありません。

結論として、APIはこれらのバックスラッシュを挿入しないように修正する必要がありますが、それが修正されるまで、上記を使用して発生する可能性のあるバックスラッシュを削除できます。


以下のコメントの議論では、文字列のバックスラッシュについて非常に混乱しているようです。それでは、少し戻って「文字列リテラル」について説明しましょう。 ドキュメント にあるように、文字列リテラルは次のとおりです。

事前定義されたString値を文字列リテラルとしてコード内に含めることができます。文字列リテラルは、二重引用符("")のペアで囲まれたテキスト文字の固定シーケンスです。

文字列リテラルは、コード内の特定の固定された文字シーケンスの単なる表現であることに注意してください。ただし、これを基になるStringオブジェクト自体と混同しないでください。文字列リテラルと基になるStringオブジェクトの主な違いは、文字列リテラルでは、特殊文字を表す(または を行うときに使用される)「エスケープ」文字としてバックスラッシュを使用できることです。文字列補間 )。 ドキュメントにあるように

文字列リテラルには、次の特殊文字を含めることができます。

  • エスケープされた特殊文字\0(ヌル文字)、\\(バックスラッシュ)、\t(水平タブ)、\n(改行)、\r(キャリッジ) return)、\"(二重引用符)および\'(一重引用符)
  • \u{n}として記述された任意のUnicodeスカラー。ここで、nは、有効なUnicodeコードポイントに等しい値を持つ1〜8桁の16進数です。

したがって、文字列リテラルでは、上記で引用した抜粋が指摘しているように、エスケープされていない円記号を使用することはできません。したがって、文字列リテラルで単一の円記号を表す場合は常に、\\で表します。

したがって、上記のstringByReplacingOccurrencesOfStringは、「string1を調べて、単一のバックスラッシュのすべての出現箇所を見つけ、それらを空の文字列に置き換える(つまり、バックスラッシュを削除する)」ことを意味します。

考えてみましょう:

let string1 = "foo\\bar"

print(string1)                    // this will print "foo\bar"
print(string1.characters.count)   // this will print "7", not "8"

let string2 = string1.stringByReplacingOccurrencesOfString("\\", withString: "")

print(string2)                    // this will print "foobar"
print(string2.characters.count)   // this will print "6"

少し紛らわしいことに、[デバッグ]パネルの[変数]ビューまたはプレイグラウンド内でstring1を見ると、文字列リテラル表現が表示されます(つまり、円記号は"\\"として表示されます)。しかし、混乱しないでください。文字列リテラルに\\が表示されている場合、実際の文字列にはバックスラッシュが1つしかありません。ただし、値をprintするか、実際の文字を見ると、文字列自体にバックスラッシュが1つだけあります。

つまり、文字列リテラル内のバックスラッシュのエスケープ(たとえば、stringByReplacingOccurrencesOfStringへのパラメーター)と、基になる文字列に存在する単一のバックスラッシュを混同しないでください。

7
Rob

私はこのコードで解決しました:

let convertedStr = jsonString.replacingOccurrences(of: "\\/", with: "/") 
2
DungeonDev

以下のコードを確認してください。

let jsonStr = "[{\"isSelected\":true,\"languageProficiencies\":[{\"isSelected\":true,\"name\":\"Advance\"},{\"isSelected\":false,\"name\":\"Proficient\"},{\"isSelected\":false,\"name\":\"Basic\"},{\"isSelected\":false,\"name\":\"Below Basic\"}],\"name\":\"English\"},{\"isSelected\":false,\"languageProficiencies\":[{\"isSelected\":false,\"name\":\"Advance\"},{\"isSelected\":false,\"name\":\"Proficient\"},{\"isSelected\":false,\"name\":\"Basic\"},{\"isSelected\":false,\"name\":\"Below Basic\"}],\"name\":\"Malay\"},{\"isSelected\":false,\"languageProficiencies\":[{\"isSelected\":false,\"name\":\"Advance\"},{\"isSelected\":false,\"name\":\"Proficient\"},{\"isSelected\":false,\"name\":\"Basic\"},{\"isSelected\":false,\"name\":\"Below Basic\"}],\"name\":\"Chinese\"},{\"isSelected\":false,\"languageProficiencies\":[{\"isSelected\":false,\"name\":\"Advance\"},{\"isSelected\":false,\"name\":\"Proficient\"},{\"isSelected\":false,\"name\":\"Basic\"},{\"isSelected\":false,\"name\":\"Below Basic\"}],\"name\":\"Tamil\"}]"
let convertedStr = jsonStr.replacingOccurrences(of: "\\", with: "", options: .literal, range: nil)
print(convertedStr)
1
Bera Bhavin

単一のバックスラッシュを削除するには、これを試してくださいlet replaceStr = backslashString.replacingOccurrences(of: "\" "、with:" ")

1
KnightOwl

余分なバックスラッシュを追加して、文字列にバックスラッシュを含めます。

1
Vincent