RegEx изменить значение Backreference - PullRequest
1 голос
/ 30 июля 2010

Есть ли способ изменить значение обратной ссылки?

Пример: В следующем тексте

"this is a test"

слово «тест» следует извлечь и вставить в другой текст с помощьюобратная ссылка.

Регулярное выражение:

(test)

Замена:

"this is another \1"

Пока все отлично работает.Но теперь вопрос в том, возможно ли изменить обратную ссылку перед вставкой.Что-то вроде преобразования слова «тест» в верхний регистр.

Я думаю, это может выглядеть так:

"this is another \to_upper\1"

Есть ли что-то определенное в «стандарте» (есть ли вообще какой-либо стандарт?) регулярных выражений?

1 Ответ

4 голосов
/ 30 июля 2010

Многие реализации (javascript, python и т. Д.) Позволяют вам указывать функцию в качестве параметра замены. Функция обычно принимает в качестве аргументов всю совпавшую строку, ее положение во входной строке и захваченные группы. Строка, возвращаемая этой функцией, используется в качестве текста замены.

Вот как это сделать с помощью JavaScript: функция replace принимает всю совпадающую подстроку в качестве первого аргумента, значение захваченных групп в качестве следующих n аргументов, за которым следует индекс совпадающей строки в исходной входной строке и вся входная строка.

var s = "this is a test. and this is another one.";
console.log("replacing");
r = s.replace(/(this is) ([^.]+)/g, function(match, first, second, pos, input) {
  console.log("matched   :" + match);
  console.log("1st group :" + first);
  console.log("2nd group :" + second);
  console.log("position  :" + pos);
  console.log("input     :" + input);
  return "That is " + second.toUpperCase();
});
console.log("replaced string is");
console.log(r);

Ouput:

replacing
matched   :this is a test
1st group :this is
2nd group :a test
pos       :0
input     :this is a test. and this is another one.
matched   :this is another one
1st group :this is
2nd group :another one
pos       :20
input     :this is a test. and this is another one.
replaced string is
That is A TEST. and That is ANOTHER ONE.

А вот версия Python - она ​​даже дает начальные / конечные значения для каждой группы:

#!/usr/bin/python
import re
s = "this is a test. and this is another one.";
print("replacing");

def repl(match):
    print "matched   :%s" %(match.string[match.start():match.end()])
    print "1st group :%s" %(match.group(1))
    print "2nd group :%s" %(match.group(2))
    print "position  :%d %d %d" %(match.start(), match.start(1), match.start(2))
    print "input     :%s" %(match.string)
    return "That is %s" %(match.group(2).upper())

print "replaced string is \n%s"%(re.sub(r"(this is) ([^.]+)", repl, s)) 

Выход:

replacing
matched   :this is a test
1st group :this is
2nd group :a test
position  :0 0 8
input     :this is a test. and this is another one.
matched   :this is another one
1st group :this is
2nd group :another one
position  :20 20 28
input     :this is a test. and this is another one.
replaced string is 
That is A TEST. and That is ANOTHER ONE.
...