Регулярное выражение Vim для удаления почти последних двух цифр числа

Используйте combn (правда, не случайно).

n <- 5
out <- combn(n:1, n - 1)
out
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    5    5    5    5    4
#[2,]    4    4    4    3    3
#[3,]    3    3    2    2    2
#[4,]    2    1    1    1    1

Перетасуйте каждый столбец, если необходимо

set.seed(1)
apply(combn(n:1, n - 1), 2, sample)

Если вы ищете эффективность, используйте решение, которое я опубликовал;)

library(microbenchmark)
n <- 1000
set.seed(1)
benchmark <- microbenchmark(
  akrun = vapply(seq_len(n), function(i) sample(setdiff(seq_len(n), i)), numeric(n-1)),
  markus = apply(combn(n:1, n - 1), 2, sample),
  A_Stam = create_matrix(n),
  times = 30L
)

[ 116] enter image description here

benchmark
#Unit: milliseconds
#   expr        min         lq       mean     median         uq        max neval
#  akrun   64.32350   66.99177   73.61685   71.15608   78.79612  104.99161    30
# markus   51.65092   53.01034   59.80802   58.48310   64.76143   78.35348    30
# A_Stam 1331.52882 1379.70371 1470.31044 1407.89861 1548.28011 1896.22913    30

8
задан ib. 10 July 2011 в 02:31
поделиться

5 ответов

Группа 3 определяется как являющийся 2 цифрами долго. Если Вы хотите соответствовать последним 4 цифрам, Вы хотите \(\d\d\d\d\) без * в конце. Если Вы просто хотите соответствовать всем цифрам, но первые 4, поместите Ваш * в соответствии группы, а не снаружи.

1
ответ дан 5 December 2019 в 19:03
поделиться

Как записано, Ваш regex получает одну цифру, затем три цифры, затем любое количество групп из двух цифр каждый. Третье соответствие, поэтому, всегда будет двумя цифрами, если оно будет существовать. В Вашем конкретном тестовом сценарии, эти '89' находится в \4, не \3.

Изменение regex к

 1,$s/\(\d\)\(\d\d\d\)\(\d\d\+\)\>/\3\g

даст Вам '6789' как результат, так как он получит две или больше цифры (до столько, сколько там) в третьей группе.

4
ответ дан 5 December 2019 в 19:03
поделиться

Вы хотите использовать негруппу фиксации здесь, как так

1,$s/\(\d\)\(\d\d\d\)\(\%(\d\d\)*\)\>/\3/g

который дает 6789 как результат здесь, и если введенный был изменен на

2345678

изменил бы строку на 278

4
ответ дан 5 December 2019 в 19:03
поделиться

Вы, вероятно, хотели бы (нуждайтесь в дополнительной группе обертывания):

%s/\(\d\)\(\d\d\d\)\(\(\d\d\)*\)\>/\3\g

Хотя я не уверен, почему Вы получаете первые 2 группы.

0
ответ дан 5 December 2019 в 19:03
поделиться

Я пробовал этот вариант в nvi и он не работает. В vim он работает, только вы должны исправить последнее инвертированное тире перед g на тире, вот так:

1,$s/\(\d\)\(\d\d\d\d\d\)\(\d\d\d\d\)*\>/\3/g

и оно заменяется на 89. Причина в том, что с помощью * вы говорите, что последнее \d\d может повторяться ноль, один или несколько раз, а с помощью > вы говорите о границе конечного слова. С группой 3 вы говорите, что вам нужна группа las, но из-за * последние две цифры (\d\d) равны 89. Убрав *>, вы можете получить 6789. Вот так:

1,$s/\(\d\)\(\d\d\d\d\)\(\d\d\d\)\(\d\d\d\)/\3/g

Следите за >, который играет хитрую роль, потому что с этим: :1,$s/\(\d\)\(\d\d\d\d\d\)\(\d\d\d\d\)\>/\3 вы получите 2389 LOL! Потому что с точки зрения конца слова-границы dddddd соответствует 456789 и заменяется двумя последними dd, а это 89. Таким образом, вы получаете 23+89 Потрясающе! LOL

0
ответ дан 5 December 2019 в 19:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: