2016-01-08 3 views
3

Я прочитал пример кода от golang.org website. По существу, код выглядит следующим образом:Go ReplaceAllString

re := regexp.MustCompile("a(x*)b") 
fmt.Println(re.ReplaceAllString("-ab-axxb-", "T")) 
fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1")) 
fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1W")) 
fmt.Println(re.ReplaceAllString("-ab-axxb-", "${1}W")) 

Выход таков:

-T-T- 
--xx- 
--- 
-W-xxW- 

Я понимаю, первый выход, но я не понимаю, остальные три. Может кто-нибудь объяснить мне результаты 2,3 и 4. Спасибо.

+0

Вы прочитали текст сразу над примером кода? – ruakh

+0

Да, я читал. Но я все еще не понимаю, как работает расширение. –

ответ

2

Самым интересным является линия fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1W")). docs say:

Внутри REPL, $ знаки интерпретируются как в Expand

И Expand говорит:

В шаблоне, переменная обозначается подстроки вида $name или ${name}, где имя - непустая последовательность букв, цифр и символов подчеркивания. Ссылка на вне диапазона или непревзойденный индекс или имя, которое отсутствует в регулярном выражении, заменяется пустым фрагментом.

В $name форме, название взято, чтобы быть как можно дольше: $1x эквивалентно ${1x}, не ${1}x, и, $10 эквивалентно ${10}, а не ${1}0.

Так, в 3-й замене, $1W рассматриваются как ${1W} и так как эта группа не инициализирована, пустая строка используется для замены.

Когда я говорю «группа не инициализирована», я хочу сказать, что группа не определена в шаблоне регулярных выражений, поэтому она не была заполнена во время операции . Замена означает получение всех совпадений, а затем их заменяет шаблон замены. Обратные ссылки ($xx) заселены во время , соответствующие фазе. Группа $1W отсутствует в шаблоне, таким образом, она не была заполнена во время , соответствующей, и только когда пустая строка используется, когда заменяется на.

2-я и 4-я замены легко понятны и описаны в приведенных выше ответах. Всего $1 обратные_связи персонажи захватил с первой группой захвата (подшаблон заключенного с парой неэкранированных скобок), то же самым с примером 4.

Вы можете думать о {} как средство неоднозначности замены шаблон.

Теперь, если вам нужно сделать результаты последовательны, используйте с именем захвата(?P<1W>....):

re := regexp.MustCompile("a(?P<1W>x*)b") // <= See here, pattern updated 
fmt.Println(re.ReplaceAllString("-ab-axxb-", "T")) 
fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1")) 
fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1W")) 
fmt.Println(re.ReplaceAllString("-ab-axxb-", "${1}W")) 

Результаты:

-T-T- 
--xx- 
--xx- 
-W-xxW- 

2-й и 3-й линии в настоящее время производят последовательный выход, так как названная группа 1W также является первой группой и $1 пронумерованными точками обратной ссылки к тому же тексту, записанному с именованным захватом $1W.

+0

Что вы имели в виду под названием 'this group is not initialized'? Как инициализировать группу? Извините, мой вопрос может быть наивным. –

+0

Группа не указана в шаблоне регулярных выражений, таким образом, она не была * заполнена * во время операции совпадения.Замена означает получение всех совпадений, а затем их заменяет шаблон замены. * Backreferences * ('$ xx') заполняются во время фазы * соответствия *. Группа «$ 1W» отсутствует в шаблоне, поэтому она не была заполнена во время сопоставления, и при замене фазы используется только пустая строка. –

+0

Что делать, если я хочу получить $ 1W? Я пытаюсь получить образование по названной группе. –

1

$ номер или $ имя индекс подгруппы в регулярных выражений или подгруппы имени

fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1")) 

$ 1 является подгруппой 1 в регулярном выражении = x*

fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1W")) 

$ 1W без имени подгруппы 1W => Заменить все с нулем

fmt.Println(re.ReplaceAllString("-ab-axxb-", "${1}W")) 

$ 1 и $ {1} - то же самое. заменить все подгруппы 1 с W

для получения дополнительной информации: https://golang.org/pkg/regexp/

+0

Спасибо. Можете ли вы объяснить второй результат немного больше? –

+0

Ok, $ name all character после $ is name, поэтому нет ключа replace => replace key = null, если не найти имя группы, он будет использовать по умолчанию regex a (x *) b и заменить нулевым ключом – trquoccuong

+0

Спасибо за узнав об этой группе. –

0

$1 является сокращением для ${1}

${1} это значение первого (1), например, группы, содержимое первой пары(). Эта группа составляет (x*), то есть любое число x.

ReplaceAllString заменяет каждое совпадение. Есть два матча. Первый - ab, второй - axxb.

Нет 2. заменяет любое совпадение содержимым группы: Это «» в первом совпадении и «xx» во втором.

Нет 4. добавляет «W» после содержимого группы.

No 3. Оставлено как упражнение. Подсказка: двенадцатая группа захвата будет составлять 12 долларов.

+0

Итак, могу ли я понять, что замена является динамической для каждого матча? –

+0

Спасибо. Вы ответили мне, чтобы понять второй результат. –

+0

Мы не пишем математическую книгу здесь, оставляя вещи в качестве упражнения. – snorberhuis

Смежные вопросы