1

For example, if I have:

"+----+----+---+---+--+"

is it possible to replace from second to fourth + to -?

If I have

"+----+----+---+---+--+"

and I want to have

"+-----------------+--+"

I have to replace from 2-nd to 4-th + to -. Is it possible to achieve this by regex? and how?

Right leg
  • 16,080
  • 7
  • 48
  • 81
Avo Asatryan
  • 404
  • 8
  • 21

6 Answers6

5

If you can assume the first character is always a +:

string = '+' + re.sub(r'\+', r'-', string[1:], count=3)

Lop off the first character of your string and sub() the first three + characters, then add the initial + back on.

If you can't assume the first + is the first character of the string, find it first:

prefix = string.index('+') + 1
string = string[:prefix] + re.sub(r'\+', r'-', string[prefix:], count=3)
glibdud
  • 7,550
  • 4
  • 27
  • 37
  • nice. but i had choosed the nubers 2 and 4 just for example. and what i need to do if i need to change from 10 to 15? – Avo Asatryan Sep 08 '17 at 14:47
  • what is the role or `r` in `r'\+'` ? – quant Sep 08 '17 at 14:47
  • @Avo replace `count=3` with `count=j-i` – Zinki Sep 08 '17 at 14:49
  • 1
    its means that the tring is regex. for example r"\b". withour r i need to write "\\b" – Avo Asatryan Sep 08 '17 at 14:49
  • 1
    @quant It makes the string a raw mode string, which allows you to enter `\\` characters without escaping them. Useful in regexes. – glibdud Sep 08 '17 at 14:50
  • 1
    @quant it means the string is a "raw" string, meaning special characters do not get evaluated, which is useful because that means the backslash goes through to the regex, otherwise you'd need double backslashes to first escape the backslash for the regex, which then escapes the plus IN the regex. – Zinki Sep 08 '17 at 14:50
  • @Zinki , in this case it wil change from second to 7 – Avo Asatryan Sep 08 '17 at 14:50
  • 1
    @AvoAsatryan In that case, [find the nth occurence of `+` in the string](https://stackoverflow.com/questions/1883980/find-the-nth-occurrence-of-substring-in-a-string), and plug that in in place of the first line of my second example, and change the `count` parameter accordingly. – glibdud Sep 08 '17 at 14:58
2

I would rather iterate over the string, and then replace the pluses according to what I found.

secondIndex = 0
fourthIndex = 0
count = 0
for i, c in enumerate(string):
    if c == '+':
        count += 1
    if count == 2 and secondIndex == 0:
        secondIndex = i
    elif count == 4 and fourthIndex == 0:
        fourthIndex = i

string = string[:secondIndex] + '-'*(fourthIndex-secondIndex+1) + string[fourthIndex+1:]

Test:

+----+----+---+---+--+
+-----------------+--+
Right leg
  • 16,080
  • 7
  • 48
  • 81
2

I split the string into an array of strings using the character to replace as the separator.

Then rejoin the array, in sections, using the required separators.

example_str="+----+----+---+---+--+"

swap_char="+"
repl_char='-'
ith_match=2
jth_match=4

list_of_strings = example_str.split(swap_char)

new_string = ( swap_char.join(list_of_strings[0:ith_match]) + repl_char +
               repl_char.join(list_of_strings[ith_match:jth_match]) +
               swap_char + swap_char.join(list_of_strings[jth_match:]) )

print (example_str)
print (new_string)

running it gives :

$ python ./python_example.py
+----+----+---+---+--+
+-------------+---+--+
R.Sharp
  • 296
  • 1
  • 8
2

with regex? Yes, that's possible.

^(\+-+){1}((?:\+[^+]+){3})

explanation:

^
(\+-+){1}                  # read + and some -'s until 2nd +
(                          # group 2 start
(?:\+[^+]+){3}             # read +, followed by non-plus'es, in total 3 times
)                          # group 2 end

testing:

$ cat test.py
import re

pattern = r"^(\+-+){1}((?:\+[^+]+){3})"

tests = ["+----+----+---+---+--+"]

for test in tests:
    m = re.search(pattern, test)
    if m:
        print (test[0:m.start(2)] + 
               "-" * (m.end(2) - m.start(2)) +
               test[m.end(2):])

Adjusting is simple:

^(\+-+){1}((?:\+[^+]+){3})
        ^              ^
  • the '1' indicates that you're reading up to the 2nd '+'
  • the '3' indicates that you're reading up to the 4th '+'
  • these are the only 2 changes you need to make, the group number stays the same.

Run it:

$ python test.py
+-----------------+--+
Marc Lambrichs
  • 2,864
  • 2
  • 13
  • 14
1

Using only comprehension lists:

s1="+----+----+---+---+--+"
indexes = [i for i,x in enumerate(s1) if x=='+'][1:4]
s2 = ''.join([e if i not in indexes else '-' for i,e in enumerate(s1)])

print(s2)
+-----------------+--+

I saw you already found a solution but I do not like regex so much, so maybe this will help another! :-)

KrazyMax
  • 939
  • 6
  • 16
1

This is pythonic.

import re
s = "+----+----+---+---+--+"
idx = [ i.start() for i in re.finditer('\+', s) ][1:-2]
''.join([ j if i not in idx else '-' for i,j in enumerate(s) ])

However, if your string is constant and want it simple

print (s)
print ('+' + re.sub('\+---', '----', s)[1:])

Output:

+----+----+---+---+--+
+-----------------+--+
Transhuman
  • 3,527
  • 1
  • 9
  • 15