0

I want to replace the character ي (Unicode:\u064A) With the character ی (Unicode:\u06CC). I tried the following code:

import unicodedata as ud
normalForm = ud.normalize('NFKD','رزاﻗﻲ')
for charr in normalForm:
  if charr == 'ي':
    print('true')
    charr = charr.replace('ي','ی')
print(normalForm)

However, this code doesn't work, and it returns the same character:

رزاقي

while it should return:

رزاقی

I wanted to try replacing using their Unicode (or any other method), How can I achieve this?

BlueBlue
  • 81
  • 1
  • 8
  • 2
    `normalForm = normalForm.replace(…)`. You need to call replace on the whole string and reassign it, not just a single character. – Mark Tolonen Sep 01 '21 at 06:38
  • 2
    `charr = charr.replace('ي','ی')` doesn't impact the original string, because `charr` is a *separate string object* that exists independently of the `normalForm`. That said, `.replace` is designed to operate on entire strings already. Remember, Python *doesn't have a separate type for individual characters*. It just makes separate length-1 strings. – Karl Knechtel Sep 01 '21 at 06:40
  • @KarlKnechtel Oh yes (facepalm) Thanks! – BlueBlue Sep 01 '21 at 06:42
  • Even if you did have to iterate, you would [want to create a new string rather than modifying the original](https://stackoverflow.com/questions/1637807/modifying-list-while-iterating), possibly by using a comprehension. – Karl Knechtel Sep 01 '21 at 06:45

1 Answers1

1

Call .replace directly on the string. Python string are immutable, so you have to assign the return value to retain the change as well:

import unicodedata as ud

original = 'رزاﻗﻲ'
nfkd = ud.normalize('NFKD',original)
replaced = nfkd.replace('ي','ی')
print('orig',ascii(original),original)
print('nfkd',ascii(nfkd),nfkd)
print('repl',ascii(replaced),replaced)

Output with ASCII representation since visually they look the same:

orig '\u0631\u0632\u0627\ufed7\ufef2' رزاﻗﻲ
nfkd '\u0631\u0632\u0627\u0642\u064a' رزاقي
repl '\u0631\u0632\u0627\u0642\u06cc' رزاقی
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251