随机替换字符串的某些部分

时间:2017-10-27 08:12:38

标签: python regex string replace

问题: 有一个包含条件的字符串,我想随意用其他运算符替换运算符。

可能的解决方案:

import re
import random

s = 'operand1 > 273 and operand2 < 459 or operand3 == 42 and operand4 < 100'

# create list of operators with random replacement
repl = random.choice(['<','>','==','!='])
operators = re.findall(r'[<>]|==|!=', s)
operators[random.choice(range(len(operators)))] = repl

# create list of other parts of the string
the_rest = re.split(r'[<>]|==|!=', s)

# recombine a string
s_new = the_rest[0]
for operator, operand in zip(operators, the_rest[1:]):
    s_new += operator + operand
print(s_new)

看起来有点模糊。你能提供更好的方法吗?

感谢。

3 个答案:

答案 0 :(得分:2)

使用re.sub()函数(使用回调替换函数调用 pattern 的每次非重叠事件)都会更简单:

import random, re

s = 'operand1 > 273 and operand2 < 459 or operand3 == 42 and operand4 < 100'
operators = ['<','>','==','!=']
s_new = re.sub(r'[<>]|==|!=', lambda op: random.choice(operators), s)

print(s_new)

示例性输出:

operand1 != 273 and operand2 == 459 or operand3 > 42 and operand4 == 100

https://docs.python.org/3/library/re.html?highlight=re#re.sub

答案 1 :(得分:1)

import random
s = 'operand1 > 273 and operand2 < 459 or operand3 == 42 and operand4 < 100'
operators = ['<', '>', '==', '!=']

print(" ".join([random.choice(operators) if x in operators else x for x in s.split()]))

编辑1.我假设OP想要更换所有操作符的假设是错误的。

s.split()从字符串单词中生成一个列表,不包括空格。

从原始字符串创建一个列表,其中随机选择一个运算符来替换其中的任何给定运算符。

" ".join将列表转换为新的字符串,包括列表元素之间的空格。

编辑2.我在喝咖啡休息时回来了。这会改变一个操作员。

import random

s = 'operand1 > 273 and operand2 < 459 or operand3 == 42 and operand4 < 100'
print(s)
operators = ['<', '>', '==', '!=']

# make a list out of the string words
s_split = s.split()

# make a list of tuples (position, operator) form the list containg the string words
occurances = [(idx, x) for idx, x in enumerate(s_split) if x in operators]

# pick a random operator form the list to change
occurance_to_change = random.choice(occurances)

# pick a random operator to replace the one in the sentence and make sure they are different
operator_to_place = random.choice(operators)
while operator_to_place == occurance_to_change[1]:
    operator_to_place = random.choice(operators)

# replace the operator
s_split[occurance_to_change[0]] = operator_to_place

# put the resulting list back together to form a string
s_result = " ".join(s_split)
print(s_result)

答案 2 :(得分:0)

将随机选择的运算符的随机出现替换为随机选择的不同运算符

import random

# returns a random operator
def ran(): 
    repl = random.choice(['<','>','==','!='])
    return repl

# replaces cth occurrence of a with b in str
def ran_repl(str, a, b, c): 
    ls = [i for i in range(len(str) - len(a)+1) if str[i:i+len(a)]==a]
    str = list(str)
    str[ls[c-1]:ls[c-1]+len(a)] = b
    return ''.join(str)

s = 'operand1 > 273 and operand2 < 459 or operand3 == 42 and operand4 < 100'
print(s)

x = ran()
while x not in s:
    x = ran()

y = ran()
while y == x:
    y = ran()

l = s.count(x)
# if multiple occurrence of x in s, replace a random occurrence
if l > 1:
    n = random.randint(1,l)
    s = ran_repl(s,x,y,n)
else:
    s = s.replace(x,y)
print(s)

输出

operand1 > 273 and operand2 < 459 or operand3 == 42 and operand4 < 100
operand1 > 273 and operand2 < 459 or operand3 == 42 and operand4 == 100