String#swapcase
str.swapcase(*options) → string String#swapcase returns a new string with the case of each character reversed. Every uppercase character becomes lowercase, and every lowercase character becomes uppercase. This is useful for stylistic transformations, display formatting, or when you need to toggle case without normalizing to a specific case.
Syntax
str.swapcase
str.swapcase(*options)
The optional options parameter accepts symbols that change how Unicode characters are handled.
Basic Usage
"Hello".swapcase
# => "hELLO"
"world".swapcase
# => "WORLD"
"RuBy".swapcase
# => "rUbY"
The original string is never modified:
original = "Hello"
result = original.swapcase
original
# => "Hello"
result
# => "hELLO"
Non-alphabetic characters are left unchanged:
"123abc!@#".swapcase
# => "123ABC!@#"
"foo.bar".swapcase
# => "FOO.BAR"
Unicode Case Mapping
From Ruby 3.0 onward, swapcase uses full Unicode case mapping by default. This means accented characters and non-ASCII letters are handled:
"Über".swapcase
# => "üBER"
"Ångström".swapcase
# => "åNGSTRÖM"
"Straße".swapcase
# => "sTRASSEN"
Characters that have no case variant stay unchanged:
"123".swapcase
# => "123"
ASCII-Only Conversion
Use :ascii when you only want a-z and A-Z swapped, leaving all other characters untouched:
"Über".swapcase
# => "üBER"
"Über".swapcase(:ascii)
# => "üBER"
In this case, ü and Ö are outside the ASCII range, so they are not affected. The :ascii option is useful when you are working with mixed encodings or when non-ASCII characters should be preserved as-is.
Turkic Case Mapping
Turkish distinguishes dotted and dotless I. Use :turkic when processing Turkish text:
"ID".swapcase
# => "id"
"ID".swapcase(:turkic)
# => "ıd"
The standard swapcase converts I to ı (lowercasing) and D to d, giving "ıd". With :turkic, Ruby applies the correct Unicode case mapping for Turkish — uppercase dotted I (U+0130) becomes lowercase dotless ı (U+0131), not a regular i.
In-Place Swapping
Use swapcase! when you want to mutate the receiver:
text = "Hello"
text.swapcase!
# => "hELLO"
text
# => "hELLO"
swapcase! returns self if changes were made, or nil if the string was already in the target case:
"hello".swapcase!
# => "HELLO"
"HELLO".swapcase!
# => nil
Common Patterns
Toggle case for display
labels = ["name", "Email", "Phone"]
labels.map(&:swapcase)
# => ["NAME", "eMAIL", "pHONE"]
Process mixed-case identifiers
def normalize_id(id)
id.swapcase
end
normalize_id("User123")
# => "uSER123"
Check case-swapped equality
a = "Hello"
b = "hELLO"
a.swapcase == b
# => true
Edge Cases
Empty strings
"".swapcase
# => ""
No alphabetic characters
"123!@#".swapcase
# => "123!@#"
Turkish locale sensitivity
The Turkish locale has unusual case-mapping rules for I and İ. Always use :turkic when processing Turkish text to get correct results:
# Standard behavior (wrong for Turkish):
"İstanbul".swapcase
# => "ıSTANBUL" — dotted İ becomes ı, but should become i
# With Turkic option (correct for Turkish):
"İstanbul".swapcase(:turkic)
# => "i̇stanbul" — dotted İ becomes i with combining dot above
Characters without case mapping
Some Unicode characters do not have a case variant. These pass through unchanged:
"日本".swapcase
# => "日本"
See Also
- String#upcase — convert all characters to uppercase
- String#downcase — convert all characters to lowercase