How to capitalize sentences consisting of ?,! and punctuation at once

165 Views Asked by At

I am learning about .capitalize() and had a question.

I learned how to change lowercase letters to uppercase letters by dividing a string consisting of several sentences based on punctuation.

However, what should be done if ? and ! are mixed in the string?

Could you please tell me what is the appropriate way to change the input below to output?

  • wanted_input= "hello. my name is john. how are you? i'm fine. thank you."

  • wanted_output = "Hello. My name is john. How are you? I'm fine. Thank you."

#the wrong way i did it..

wanted_input= "hello. my name is john. how are you? i'm fine. thank you." 

def capital_with(word_list, seperater):
    
  capital_split = word_list.split(seperater)

  capital_word = []

  for i in capital_split:
      capital_word.append(i.capitalize())
    
      capital_result = seperater.join(capital_word)

  return capital_result  


wanted_input= capital_with(wanted_input,'. ')
wanted_input= capital_with(wanted_input,'? ')

print(wanted_input) #Hello. my name is john. how are you? I'm fine. thank you.

3

There are 3 best solutions below

5
VvdL On

You can find the spaces preceded by a ., ? or ! by using a regular expression and re.split. Then use str.capitalize() to give each part a capital letter at the start and use " ".join() to glue it back together. If you just want to print, you can unpack the generator.

import re

sentences = "hello. my name is john. how are you? i'm fine. thank you."

# Option 1 if you want to store the value: 
result = " ".join([s.capitalize() for s in re.split(r"(?<=[\?\.!]) ", sentences)])

# Option 2 if you just want to print as CtrlZ mentioned in the comments: 
print(*(s.capitalize() for s in re.split(r"(?<=[\?\.!]) ", sentences)))

# Hello. My name is john. How are you? I'm fine. Thank you.

(?<=[\?\.!]) This regex pattern uses positive lookbehind to find spaces preceded by ?, . or !

0
S.B On

You can use re.sub, it's like str.replace but more flexible. It accepts a pattern for substitution.

import re

pattern = r"^\w|(?<=\. |\? |! )\w"
text = "hello. my name is john. how are you? i'm fine. thank you."
print(re.sub(pattern, (lambda m_obj: m_obj.group().upper()), text))
# Hello. My name is john. How are you? I'm fine. Thank you.

The pattern says that if a character is either at the beginning(^\w) or it's after a "?!. + space" it should be matched. (The (?<=...) part is the positive look behind assertion.) This is what we want:

enter image description here

The only thing remained is we need to convert the matched character to upper case.


Edit:

You could also use the pattern

^\w|(?<=[.!?] )\w

instead. Basically the same thing but a bit shorter and simpler.

0
cocoajoa On

Thank you all. I got the answer I wanted through above answers! I'll try to learn more about useful libraries and modules.

For reference, I asked the same question to my tutor in addition to stackoverflow and got tip about it. I solved the above problem by different way. It's not as short as the answer you guys uploaded above, But I want to upload my answer to get feedback:) Thank you.

input = "hello. my name is john. how are you? i'm fine. thank you." 

# Output string
wanted_input = ''

# Capitalize the first letter and put it in output string
wanted_input = example[0].capitalize()

# Swtich for circulation, 
capital_switch = False

# The first word has already been entered, so it will cycle from the second.
for char in example[1:]:
    
    # When the switch is True and the argument is an alphabet,
    if capital_switch and char.isalpha():
        
        # Capitalize it and put in output string
        wanted_input += char.capitalize() 
        
        # Turn off the switch
        capital_switch = False

    else:
        # Just put in out put string 
        wanted_input += char 

    # If the argument is in follows:
    if char in ('.', '?', '!'):
        # Turn on the swtich
        capital_switch = True
      

print(wanted_input) #Hello. My name is john. How are you? I'm fine. Thank you.