Регулярное выражение для разделения только на определенный символ, если этот символ не в паре - PullRequest
1 голос
/ 20 декабря 2009

После нахождения самого быстрого алгоритма замены строк в этой теме я пытался изменить один из них в соответствии со своими потребностями, в частности этот от gnibbler.

Я еще раз объясню здесь проблему, и что у меня за проблема.

Скажем, у меня есть строка, которая выглядит следующим образом:

str = "The &yquick &cbrown &bfox &Yjumps over the &ulazy dog"

Вы заметите множество мест в строке, где есть амперсанд, за которым следует символ (например, «& y» и «& c»). Мне нужно заменить эти символы подходящим значением, которое у меня есть в словаре, например так:

dict = {"y":"\033[0;30m",
        "c":"\033[0;31m",
        "b":"\033[0;32m",
        "Y":"\033[0;33m",
        "u":"\033[0;34m"}

Используя решение gnibblers, предоставленное в моей предыдущей теме, я использую это в качестве текущего решения:

myparts = tmp.split('&')
myparts[1:]=[dict.get(x[0],"&"+x[0])+x[1:] for x in myparts[1:]]
result = "".join(myparts)

Это работает для правильной замены символов и не сбой для символов, которые не найдены. Единственная проблема в этом состоит в том, что не существует простого способа на самом деле сохранить амперсанд на выходе. Самым простым способом, которым я мог бы придумать, было бы изменить мой словарь на:

dict = {"y":"\033[0;30m",
        "c":"\033[0;31m",
        "b":"\033[0;32m",
        "Y":"\033[0;33m",
        "u":"\033[0;34m",
        "&":"&"}

И измените мой вызов "split", чтобы разделить регулярные выражения для амперсандов, за которыми НЕ следуют другие амперсанды.

>>> import re
>>> tmp = "&yI &creally &blove A && W &uRootbeer."
>>> tmp.split('&')
['', 'yI ', 'creally ', 'blove A ', '', ' W ', 'uRootbeer.']
>>> re.split('MyRegex', tmp)
['', 'yI ', 'creally ', 'blove A ', '&W ', 'uRootbeer.']

По сути, мне нужно регулярное выражение, которое разделится на первый амперсанд пары и каждый одиночный амперсанд, чтобы я мог выйти из него через мой словарь.

Если у кого-нибудь есть более удачные решения, пожалуйста, сообщите мне.

Ответы [ 4 ]

2 голосов
/ 20 декабря 2009

Вы можете использовать отрицательный вид сзади (при условии, что рассматриваемый механизм регулярных выражений поддерживает его), чтобы сопоставлять только амперсанды, которые не следуют за другим амперсандом.

/(?<!&)&/
0 голосов
/ 21 декабря 2009

re.sub будет делать то, что вы хотите. Он принимает шаблон регулярного выражения и может использовать функцию для обработки совпадения и возврата замены. Ниже, если символ, следующий за &, отсутствует в словаре, замена не производится. && заменяется на & для разрешения экранирования &, за которым следует символ в словаре.

Также 'str' и 'dict' являются неправильными именами переменных, потому что они скрывают встроенные функции с одинаковыми именами.

В 's' ниже '& cat' не будет затронут, и '&& cat' станет "& cat", подавляя & c перевод.

import re

s = "The &yquick &cbrown &bfox & cat &&cat &Yjumps over the &ulazy dog"

D = {"y":"\033[0;30m",
     "c":"\033[0;31m",
     "b":"\033[0;32m",
     "Y":"\033[0;33m",
     "u":"\033[0;34m",
     "&":"&"}

def func(m):
    return D.get(m.group(1),m.group(0))

print repr(re.sub(r'&(.)',func,s))

ВЫВОД:

'The \x1b[0;30mquick \x1b[0;31mbrown \x1b[0;32mfox & cat &cat \x1b[0;33mjumps over the \x1b[0;34mlazy dog'

1011 * -Марк *

0 голосов
/ 20 декабря 2009

Я думаю, что это делает трюк:

import re

def fix(text):
    dict = {"y":"\033[0;30m",
            "c":"\033[0;31m",
            "b":"\033[0;32m",
            "Y":"\033[0;33m",
            "u":"\033[0;34m",
            "&":"&"}

    myparts = re.split('\&(\&*)', text)
    myparts[1:]=[dict.get(x[0],"&"+x[0])+x[1:] if len(x) > 0 else x for x in myparts[1:]]
    result = "".join(myparts)
    return result


print fix("The &yquick &cbrown &bfox &Yjumps over the &ulazy dog")
print fix("&yI &creally &blove A && W &uRootbeer.")
0 голосов
/ 20 декабря 2009

Может быть цикл while (q = str.find ('&', p))! = -1, затем добавить левую часть (p + 2 к q - 1) и значение замены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...