2015-07-04 2 views
4

Я хочу поменять текстовые части слева направо и наоборот. Это прекрасно работает слева направо:R regexp замена текстовых частей

sub("(^x+)(.+)", "\\2\\1","xxxxx6.0") 
[1] "6.0xxxxx" 

в то время как другое направление не будет:

sub("(.+)(x+$)", "\\2\\1","6.0xxxxx") 
[1] "x6.0xxxx" 

Что мне не хватает?

+1

или вы могли бы разделить строку и обратный его 'оборотов (strsplit («xxxxx6.0»,«(? <= (x)) (?! \\ 1) ', perl = TRUE) [[1]]) ' – rawr

ответ

4

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

(6.0xxxx)(x) 

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

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

/(.+?)(x+$)/ 

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

(6.0)(xxxxx) 

Это то, что вы хотите.

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

/(^[^x]+)(+x$)/ 

Карет внутри группы соответствия указывает, что соответствующая группа инвертирована (соответствует всем, что не является x). Это будет соответствовать всем до первого x как группа 1, в результате чего будут созданы нужные группы.

+0

Работаю отлично! Спасибо за объяснение! –

3

Вы можете использовать отрицательный lookbehind (?<!...) для второго регулярного выражения, чтобы обойти тот факт, что (.+) жадный. Отрицательная просмотра назад делает это так, что (x+$) не будет соответствовать символ, который непосредственно предшествует x:

sub("(.+)(?<!x)(x+$)", "\\2\\1", "6.0xxxxx", perl=TRUE) 
#[1] "xxxxx6.0" 
+0

Спасибо за ваш ответ, работая идеально, немного сложнее, чем Strikeskids. Один взлет ... –

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