Is there a way to change a matching object returned from a regex.search() function?
<p>I am new to coding and made up a project for my self to start learning, but I could'nt get around this problem. i am trying to make a little tool which converts stuff from the clipboard(which for now I will simply use a string called <code>spam</code>) so that the sentences start with a capital letter, and in which ' i ' is also uppercase, so ' I '. </p>

<p>So what I tried to do was, find a match where there is a ('. ', '? ' or ' i ') and go from there.</p>

<pre><code>spam='this is a string which i want to correct. as you can see.'
def capital(lists):            #finds out where to change the text
    dotRegex=re.compile(r'\. ')
    questionRegex=re.compile(r'\? ')
    iRegex=re.compile(r' i ')
    mo1=dotRegex.search(lists)
    mo2=questionRegex.search(lists)
    mo3=iRegex.search(lists)
    if mo1:
        (lists(mo1.start()+2)).upper()
    if mo2:
        (lists(mo1.start()+2)).upper()
    if mo3:
        mo3.upper()
capital(spam)
</code></pre>

<p>This returns the error:</p>

<blockquote>
  <p>"(lists(mo1.start()+2)).upper() TypeError: 'str' object is not
  callable"</p>
</blockquote>

<p>What I try to do there is find where there is a <code>mo</code>, go 2 indecises to the right and change what is there to uppercase. Is there any way to do this? And offcourse the <code>search()</code> function only returns 1 <code>mo</code>, 
<strong>so my question is:</strong> is there a way to work around it when there are multiple matching objects and change them all? I know <code>findall()</code> exists but how can you use that here?</p>

<p>Anyway, I would love some help from anybody, and I am sorry if this code hurts to watch.</p>

<p>There are several errors (or awkwardnesses) in your code.</p>

<p>Here is a quick code review:</p>

<pre><code>import re

spam = 'this is a string which i want to correct. as you can see.'

def capital(lists):
    # finds out where to change the text.
    dot_regex = re.compile(r'\. ')
    question_regex = re.compile(r'\? ')
    i_regex = re.compile(r' i ')
    mo1 = dot_regex.search(lists)
    mo2 = question_regex.search(lists)
    mo3 = i_regex.search(lists)
    if mo1:
        lists[mo1.start() + 2].upper()
    if mo2:
        lists[mo1.start() + 2].upper()
    if mo3:
        mo3.group().upper()

capital(spam)
</code></pre>

<ol>
<li>According to the <a href="https://www.python.org/dev/peps/pep-0008/#prescriptive-naming-conventions" rel="nofollow">PEP8 conventions</a>, variable should be written in snake case. So I replace <code>dotRegex</code> by <code>dot_regex</code>,</li>
<li>Since you don't modify it in function, you can also use module-level variables (constant) for RegEx: for instance: <code>DOT_REGEX</code>.</li>
<li>Put spaces around binary operators: <code>mo1 = ...</code>.</li>
</ol>

<p>In Python, string indexing/slicing use <code>[]</code> operator, so replace <code>lists(mo1.start() + 2)</code> by <code>lists[mo1.start() + 2]</code>. The syntax <code>lists(...)</code> is a function call, here.</p>

<p>Remember that in Python, <a href="https://docs.python.org/2/faq/design.html#why-are-python-strings-immutable" rel="nofollow">strings are immutable</a>: so you can't modify it, you must create a copy.</p>

<pre><code>foo = "string"
foo[2] = "l"  # &lt;- TypeError: 'str' object does not support item assignment
</code></pre>

<p>To answer your question: No, you can't modify a string, but you can use a search/replace with RegEx to do what you want.</p>

<p>Here is an detailed explanation for the <code>dot_regex</code>:</p>

<pre><code>import re

# Search the first letter after a dot (or after the begining)
dot_regex = re.compile(r"(^|\. )(.)")

def my_upper(mo):
    """ Keep the dot (group #1), turn the letter in uppercase (group #2). """
    return mo.group(1) + mo.group(2).upper()

spam = 'this is a string which i want to correct. as you can see.'
spin = dot_regex.sub(my_upper, spam)
# =&gt; This is a string which i want to correct. As you can see.
</code></pre>

<p>You can continue with other RegEx...</p>

<p><em>Note:</em> to match a single "i", you can use <code>r"\bi\b"</code>:</p>

<pre><code># Search a single "i"
i_regex = re.compile(r"\bi\b")

spon = i_regex.sub("I", spin)
print(spon)
# =&gt; This is a string which I want to correct. As you can see.
</code></pre>

<p>You are doing a king of copy-editing, aren't you? ;-)</p>

<p>You can combine the rules for dot and question mark (and exclamation mark too):</p>

<pre><code># Search the first letter after a dot/?/! (or after the begining)
mark_regex = re.compile(r"(^|[!?.] )(.)")

spam = 'can you see? this is a string which i want to correct. as you can see! yeh!'
spif = mark_regex.sub(my_upper, spam)
# =&gt; Can you see? This is a string which i want to correct. As you can see! Yeh!
</code></pre>

<p><strong>TUTORIAL: <a href="https://docs.python.org/3/howto/regex.html" rel="nofollow">Regular Expression HOWTO</a></strong></p>

python regex