Remove final characters from string recursively - What's the best way to do this?
<p>I am reading lines from a file one at a time and before i store each, i wanna modify them according to the following simple rule:</p>

<ul>
<li>if the last character is not any of, e.g., <code>{'a', 'b', 'c'}</code> store the line.</li>
<li>if that is not the case, remove the character (pop-like) and check again.</li>
</ul>

<p>What i currently have (felt like the obvious thing to do) is this:</p>

<pre><code>bad_chars = {'a', 'b', 'c'}


def remove_end_del(line_string, chars_to_remove):
    while any(line_string[-1] == x for x in chars_to_remove):
        line_string = line_string[:-1]
    return line_string

example_line = 'jkhasdkjashdasjkd|abbbabbababcbccc'
modified_line = remove_end_del(example_line, bad_chars)
print(modified_line)  # prints -&gt; jkhasdkjashdasjkd|
</code></pre>

<p>Which of course works, but the string slicing\reconstruction seems a bit too excessive to my untrained eyes. So i was wondering a couple of things:</p>

<ol>
<li>is there a better way to do this? like a <code>pop</code> type of function for strings?</li>
<li>how is <code>rstrip()</code> or <code>strip()</code> in general implemented? is it also with a <strong>while</strong>?</li>
<li>would it be worthwhile making <code>rstrip()</code> recursive for this example?</li>
<li>Finally, how much better is the following:</li>
</ol>

<hr>

<pre><code>def remove_end_del_2(line_string, chars_to_remove):
    i = 1
    while line_string[-i] in chars_to_remove:
        i += 1
    return line_string[:-i+1]
</code></pre>

<p>Any comment on any of the points made above would be appreciated âº.</p>

<p><strong>Note: the separator ("|") is only there for visualization.</strong></p>

<p>Not the direct answer to the question, but one alternative option would be to use <em>regular expressions</em> to remove the bad characters at the end of the string:</p>

<pre><code>&gt;&gt;&gt; import re
&gt;&gt;&gt;
&gt;&gt;&gt; example_line = 'jkhasdkjashdasjkd|abbbabbababcbccc'
&gt;&gt;&gt; bad_chars = {'a', 'b', 'c'}
&gt;&gt;&gt;
&gt;&gt;&gt; re.sub(r'[%s]+$' % ''.join(bad_chars), '', example_line)
'jkhasdkjashdasjkd|'
</code></pre>

<p>The regular expression here is dynamically constructed from the set of "bad" characters. It would (or "could", since sets have no order) be <code>[abc]+$</code> in this case:</p>

<ul>
<li><code>[abc]</code> defines a "character class" - any of "a", "b" or "c" would be matched</li>
<li><code>+</code> means 1 or more   </li>
<li><code>$</code> defines the end of the string</li>
</ul>

<p>(Note that, if "bad" characters can contain a character that may have a special meaning in the character class (like, for example, <code>[</code> or <code>]</code>), it should be escaped with <a href="https://docs.python.org/2/library/re.html#re.escape" rel="nofollow"><code>re.escape()</code></a>).</p>

<p><sup>The last statement though may prove that <a href="http://programmers.stackexchange.com/questions/223634/what-is-meant-by-now-you-have-two-problems">old saying</a> about having more problems than initially.</sup></p>

python