2012-01-21 34 views
2

举例来说,我有以下字符串:将随机字符字符串,如果没有一定的单词

Hello how are you today, [name]? 

字的随机选择,但不是[名]之间我怎么会去随意放置字符?我已经有了下面这段代码,但我希望有更好的方法去实现它。

string = 'Hello how are you today, [name]?' 
characters = 'qwertyuioplkjhgfdsazxcvbnm,. ' 
arr = string.rsplit(" ") 

for i in range(0, len(arr)): 
    x = arr[i] 
    if x == '[name]': 
     continue 
    if (random.randint(0,2)==1) : 
     rnd=random.randint(1,len(x)-2) 
     tmp1 = random.randint(0,len(characters)) 
     rndCharacter = characters[tmp1:tmp1+1] 
     x = x[0:rnd] + rndCharacter + x[rnd+1:] 
     arr[i] = x 

" ".join(arr) 

> Hellio how are yoy todsy, [name]?" 

虽然这会用另一个随机字符替换字符。我会以什么方式随机替换或在角色之前或之前放置一个随机角色?

基本上我只是想模拟一种错字发生器。

感谢

在我的代码更新至今:

string = 'Hey how are you doing, [name]?' 
characters = 'aeiou' 
arr = string.rsplit(" ") 
for i in range(0, len(arr)): 
    x = arr[i] 
    if x == '[name]': continue 
    if len(x) > 3: 
     if random.random() > 0.7: 
      rnd = random.randint(0,len(x)-1) 
      rndCharacter = random.choice(characters) 
      if random.random() > 0.7: 
       x = x[0:rnd] + rndCharacter + x[rnd+1:] 
      else: 
       x = x[:rnd] + rndCharacter + x[rnd:] 
      arr[i] = x 
    else: 
     if random.random() > 0.7: 
      rnd = random.randint(0,len(x)-1) 
      rndCharacter = random.choice(characters) 
      x = x[:rnd] + rndCharacter + x[rnd:] 
      arr[i] = x 
print " ".join(arr) 

> Hey houw are you doiang, [name]? 

UPDATE:

也许我的代码最后的更新,希望这将帮助别人出一些点在未来

def misspeller(word): 
    typos = { 'a': 'aqwedcxzs', 
       'b': 'bgfv nh', 
       'c': 'cdx vf', 
       'd': 'desxcfr', 
       'e': 'e3wsdfr4', 
       'f': 'fredcvgt', 
       'g': 'gtrfvbhyt', 
       'h': 'hytgbnju', 
       'i': 'i8ujko9', 
       'j': 'juyhnmki', 
       'k': 'kiujm,lo', 
       'l': 'loik,.;p', 
       'm': 'mkjn ,', 
       'n': 'nhb mjh', 
       'o': 'o9ikl;p0', 
       'p': 'p0ol;[-', 
       'q': 'q1asw2', 
       'r': 'r4edft5', 
       's': 'swazxde', 
       't': 't5rfgy6', 
       'u': 'u7yhji8', 
       'v': 'vfc bg', 
       'w': 'w2qasde3', 
       'x': 'xszcd', 
       'y': 'y6tghu7', 
       'z': 'zaZxs', 
       ' ': ' bvcnm', 
       '"': '"{:?}', 
       '\'': '[;/\']', 
       ':': ':PL>?"{', 
       '<': '<LKM >', 
       '>': '>:L<?:', 
       ';': ';pl,.;[', 
       '[': '[-p;\']=', 
       ']': '=[\'', 
       '{': '{[_P:"}+', 
       '}': '}=[\']=', 
       '|': '|\]\'', 
       '.': '.l,/;', 
       ',': ',lkm.' 
      } 

    index = random.randint(1,len(word)-1) 
    letter = list(word[:index])[-1].lower() 
    try: 
     if random.random() <= 0.5: 
      return word[:index] + random.choice(list(typos[letter])) + word[index:] 
     else: 
      return word[:index-1] + random.choice(list(typos[letter])) + word[index:] 
    except KeyError: 
     return word 

def generate(self, s, n, safe_name): 
    misspelled_s = '' 
    misspelled_list = [] 
    for item in s.split(' '): 
     if n: 
      if safe_name in item: 
       misspelled_list.append(item) 
      else: 
       r = random.randint(0,1) 
       if r == 1 and len(re.sub('[^A-Za-z0-9]+', '', item)) > 3: 
        misspelled_list.append(misspeller(item)) 
        n -= 1 
       else: 
        misspelled_list.append(item) 
     else: 
      misspelled_list.append(item) 
    return ' '.join(misspelled_list) 
+0

从输入“你好,你今天怎么样,[名字]? ? – FakeRainBrigand

+0

对不起,像这样的东西“Hellio怎么样,同性恋,[姓名]?” – mikeyy

+0

那么'[name]'实际上是在括号内吗?或者名字会成为一个真实的名字,比如'today,mike'? (有时候人们会在占位符不会真正出现在输入中时使用占位符。) – FakeRainBrigand

回答

2
import random 

def misspeller(word): 
    characters = 'qwertyuioplkjhgfdsazxcvbnm,. ' 
    rand_word_position = random.randint(-1,len(word)) 
    rand_characters_position = random.randint(0,len(characters)-1) 

    if rand_word_position == -1: 
     misspelled_word = characters[rand_characters_position] + word 
    elif rand_word_position == len(word): 
     misspelled_word = word + characters[rand_characters_position] 
    else: 
     misspelled_word = list(word) 
     misspelled_word[rand_word_position] = characters[rand_characters_position] 
     misspelled_word = ''.join(misspelled_word)   
    return misspelled_word 

s = 'Hello how are you today, [name]?' 
misspelled_s = '' 
misspelled_list = [] 
for item in s.split(' '): 
    if '[name]' in item: 
     misspelled_list.append(item) 
    else: 
     misspelled_list.append(misspeller(item)) 
misspelled_s = ' '.join(misspelled_list) 
print misspelled_s 

的例子是:

'Hellk howg ars youf poday, [name]?' 
'Heylo how arer y,u todab, [name]?' 
'Hrllo hfw are zyou totay, [name]?' 

编辑清理第一个副本上的一些错误和遗漏。

编辑2如果你不想受到影响的每一个字,你可以修改为按以下方式循环:

for item in s.split(' '): 
    n = random.randint(0,1) 
    if '[name]' in item: 
     misspelled_list.append(item) 
    elif n == 1: 
     misspelled_list.append(misspeller(item)) 
    else: 
     misspelled_list.append(item) 

您可以修改一个字是通过改变如何修改的概率例如,生成了nn = random.randint(0,10)

+0

谢谢,好的先生! – mikeyy

2

如果你想之前或代替replacin后放置了一封信克,刚修好你的拼接指数,让他们不要过度字母跳转 - 即使用

x = x[:rnd] + rndCharacter + x[rnd:] 

这样的新角色将在中间插入,而不是替换现有的一个。

此外,您还可以使用rndCharacter = random.choice(characters),而不是使用tmp1这样。

+0

谢谢,我已经使用了提供的代码。 :) – mikeyy

0

对于你给的例子,它看起来像我们可以逗号分开,并把错字(收费)字符串的第一部分。

如果这是正确的,你需要生成错字之前做随机三两件事:

  • 选择做哪个字符上或附近
  • 选择错字字错字
  • 选择之一三个动作 - 替换,前缀,追加

这是否符合法案?

(顺便说一句,因为你熟悉随机的,我没有给任何代码)就是我从misspelled_s得到的

1

我认为@sgallen的答案会有效,但我有一些提示(对于您以前的代码,并向前)。

for i in range(0, len(arr)): 
    x = arr[i] 

# is the same as 

for i,x in enumerate(arr): 

else: 
    if random...: 

# to 

elif random...: 

使用string作为一个变量的名字,是不是一个好的做法。原因是,有一个string模块。它可能因为string constants而派上用场。替代方案可能是inpdatasentence

# For example 

>>> import string 
>>> string.lowercase 
'abcdefghijklmnopqrstuvwxyz' 

顺便说一句,如果有人在上面注意到的错误,发表评论。谢谢。

+0

非常感谢帮助的人! – mikeyy

1

您还可以使用split('[name]'),并在子串的工作,这样你一定会(参见下面的注释)的不改变'[name]'

您可能对每一个[name]次数醒目一些较长的名称的一些子问题分裂,但如果你:在大写字母(如Jonh)

  • 使用真实姓名。
  • 避免使用类似的名称。

然后将以下代码应该很好地工作:

def typo(string): 
    index = random.randint(1,len(string)-1) # don't change first or last 
    return string[:index] + random.choice(characters) + string[index:] 

def generate(string, n, safe_name): 
    sub_strings = string.split(safe_name) 
    while n: 
     sub_index = random.randint(0,len(sub_strings) - 1) 
     sub = sub_strings[sub_index] 
     if len(sub) <= 2: # if too short don't change 
      continue 

     sub_strings[sub_index] = typo(sub) 
     n -= 1 
    return safe_name.join(sub_strings) 

实施例添加3新的随机charachter:

>>> string = 'Hello how are you today, Alice?' 
>>> generate(string, 3, 'Alice') 
'Hellov howj are yoiu today, Alice?' 

随着名称存在多于一个时间:

>>> string = 'Hello Alice, how are you today, Alice?' 
>>> generate(string, 3, 'Alice') 
'Hello Alice, hoiw arfe you todayq, Alice?' 
+0

不错!我真的很喜欢这个,因为我可以定义我想要发生多少错别字。在我面前思考,谢谢! – mikeyy

0

你“希望有更好的方式去做”。那么,这里有一些建议,以及一些展示这些建议的代码。一些建议是关于使代码更加pythonic或易于阅读,而不仅仅是改变字符串的机制。

  1. 使用module re for regular expressions来检测“[name]”。只要您的关键字多于此关键字,这将会带来好处。
  2. for x in string.rsplit(" ")是循环遍历单词的一种更为pythonic的方式。
  3. 获取实数偶数,并将其与0.0-1.0范围内的概率设置进行比较。比得到整数0,1更灵活。
  4. 按照其他人的建议使用x[:rnd] + ... + x[rnd:x],以简化字符串操作。
  5. 使用x if condition else y作为选择之间的简明选择,在这种情况下导致覆盖的索引和导致插入的索引之间的选择。
  6. 您的示例输出显示在“您”中插入的拼写错误,但您的示例代码仅在len(x) > 3插入拼写错误。我遵循你的代码,但这很容易改变。

希望这会有所帮助。

import random 
import re 

string = 'Hello how are you today, [name]?' 
characters = 'qwertyuioplkjhgfdsazxcvbnm,. ' 
words = [] 

for x in string.rsplit(" "): 
    if None == re.search('[^\]]*\[[a-z]+\].*', x) \ 
     and len(x) > 3 and random.random()<=0.5: 
     # rnd: index of char to overwrite or insert before 
     rnd = random.randint(2,len(x)-2) 
     # rnd1: index of 1st char after modification 
     # random.random <= 0.x is probability of overwriting instead of inserting 
     rnd1 = rnd + 1 if random.random() <= 0.5 else 0 
     x = x[:rnd] + random.choice(characters) + x[rnd1:] 

    words.append(x) 

typos = " ".join(words) 
print typos 

更新:代码中的固定缩进错误。

更新2:使选择覆盖与插入的代码更加简洁。

+0

谢谢!这看起来比我的更清洁。 – mikeyy

相关问题