RegEx для захвата и замены цифр в шаблоне - PullRequest
1 голос
/ 26 мая 2019

Я бы хотел заменить третий аргумент в строке новым числом (скажем, 100). Соответствующая строка всегда начинается с function, с первым аргументом либо true или false, а с номером в качестве второго аргумента.

                                               Expected
                    |                             |
                    v                             v
'function(true, 0, 15)'   --> 'function(true, 0, 100)'  
'function(false, 0, 23)'  --> 'function(false, 0, 100)'

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

import re
string = 'function(true, 0, 15)'
regex = re.compile('function\([a-zA-Z]*, [0-9]*, ([0-9]*)\)')
res = re.sub(regex, '100', string)

print(res) # 100
           # Expected: function(true, 0, 100)

Вопрос: Не могли бы вы указать мне, почему вышеприведенный код не работает? Как бы я написал код для достижения ожидаемого результата?

Ответы [ 3 ]

3 голосов
/ 26 мая 2019

Поскольку за номером, который вы пытаетесь заменить, следует только закрывающая скобка ), вы можете просто использовать это \d+(?=\s*\)) регулярное выражение и заменить его на 100 или любое другое значение, которое вы хотите. Попробуйте эти коды Python,

import re
string = 'function(true, 0, 15)'
regex = re.compile(r'\d+(?=\s*\))')
res = re.sub(regex, '100', string)

print(res)

печать

function(true, 0, 100)

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

Regex Demo соответствует только тому, что вы хотите заменить

И ваше текущее регулярное выражение соответствует всему вашему вводу, как показано в демонстрационном примере ниже,

Regex Demo с вашим регулярным выражением, совпадающим со всем вводом

Кроме того, если вы чувствуете себя лучше и хотите сопоставить весь ввод, а затем выборочно заменить только третий аргумент, вы можете использовать это регулярное выражение для захвата имени функции и первых двух параметров в group1, как вы хотели захватить в исходном регулярном выражении.

(function\([a-zA-Z]*, [0-9]*, )[0-9]*\)

и замените его на \g<1>100), где \g<1> ссылается на значение, захваченное в группе1, и далее оно заменяется на 100)

Regex Demo с полным совпадением и выбранной заменой

1 голос
/ 26 мая 2019

В качестве альтернативы, вы можете напечатать все до матча и все после матча, а затем распечатать его с новым результатом, например так:

regex = re.compile( '(function\([a-zA-Z]*, [0-9]*, )([0-9]*)(\))' )
res = re.sub( regex, r'\1 100\3', string )

По сути, я поместил скобки вокруг текста перед ожидаемымматч и после ожидаемого матча.Затем я распечатываю его как \1 (первое совпадение) 100 (новый текст) \3 (третье совпадение).

Причина, по которой я предлагаю это конкретное выражение, заключается в том, что OP нужно толькосопоставлять строки, которые также содержат предшествующий раздел «function (» (или некоторый другой шаблон). Плюс, это всего лишь расширение решения OP, поэтому оно может быть более интуитивно понятным для OP.

1 голос
/ 26 мая 2019

Это выражение также может работать:

(?:\d+)(\))

, в котором есть группа без захвата с желаемыми цифрами (?:\d+), за которой следует правая граница (\)), которую мы можем заменить на нашу новуючисло и $1.

Тест

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(?:\d+)(\))"

test_str = "function(true, 0, 15)"

subst = "100\\1"

# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 0, re.MULTILINE)

if result:
    print (result)

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

Демо

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