I have a sentence with plain numbers and ordinal numbers and I wanted to convert ordinal digits to words like 2 nd to Second, 56 th to Fifty sixth. I used the library num2words and below code works perfectly.
import num2words
text = "ordinal numbers are like as 42 nd, 67 th, and 5 th and plain numbers such as 1, 2, 3."
numbers = re.findall('(\d )[st|nd|rd|th]', text)
numbers
for n in numbers:
ordinalAsString = num2words.num2words(n, ordinal=True)
print(ordinalAsString)
#forty-second
#sixty-seventh
#fifth
Now I want to create a lambda function such that,
sentence = "ordinal numbers are like as 42 nd, 67 th, and 5 th and plain numbers such as 1, 2, 3."
o/p sentence = "ordinal numbers are like as fourty-second, sixty-seventh, and fifth and plain numbers such as 1, 2, 3."
I wrote the function like this,
sentence = re.sub(r"(\d )[st|nd|rd|th]", lambda x: num2words.num2words(str(x), ordinal=True), sentence)
But that throws an error like,
InvalidOperation: [<class 'decimal.ConversionSyntax'>]
What is wrong in the code?
CodePudding user response:
There are two problems:
Your regular expression isn't correctly matching the suffix, only the first letter of the suffix.
[st|nd|rd|th]
matches exactly one of the characters inside the brackets; duplicates are ignored, so it's equivalent to[st|ndrh]
, with the|
treated as a character to match like each of the letters. User"(\d )(?:st|nd|rd|th)"
instead; the|
inside the non-capture group(?:...)
does work to separate the 4 patternsst
,nd
,rd
, andth
.The callable passed to
re.sub
takes aMatch
object as its argument. You need to use itsgroup
method to extract the captured sting.lambda x: num2words.num2words(x.group(1), ordinal=True)
.