2014-12-03 23 views
2

我错误地检查格式为A1A1A1的加拿大邮政编码。 常见错别字是位置2,4或6的大写字母O而不是零,应该用0替换。R正则表达式只在特定的字符串位置选择性地替换字符

我对于正则表达式相当陌生,而这一个让我难住。 非常感谢!

+5

给出一个例子以及预期的输出。 – 2014-12-03 02:16:50

+4

我认为这个问题不应该被搁置,格式是指定的,并给出一个例子。答案似乎也解决了这个问题。投票重新开放。 – thelatemail 2014-12-03 03:53:42

回答

0

使用正则表达式如下GSUB中的功能,然后用0

(?<=^.)O|(?<=^.{3})O|(?<=^.{5})O 

DEMO

OR

您可以使用PCRE动词(*SKIP)(*F)替换所有匹配的字符。这仅将2,4,6位中的字母O替换为零0。它不会关心其他职位上的字母或数字。

> x <- c('AOAOAO', 'O2O3O2', 'BOB1B2', 'C1COC3') 
> gsub("(?:(?<=^).|(?<=^..).|(?<=^....).)(*SKIP)(*F)|O", "0", x, perl=TRUE) 
[1] "A0A0A0" "O2O3O2" "B0B1B2" "C1C0C3" 

DEMO

+0

您能否提供downvote的原因? – 2014-12-03 05:14:47

4

你可以做

x <- c("A0A0A0", "AOB0C0", "A0BOC0", "A0B0CO", "OOOOOO") 

gsub("([A-Z])O", "\\10", x) 
# [1] "A0A0A0" "A0B0C0" "A0B0C0" "A0B0C0" "O0O0O0" 

的解释了一下:

  • [A-Z]是任意字符从AZ
  • 的parenthes ES ([A-Z])在这里捕捉字符,因此它可以为\\1在替换
  • ([A-Z])O引用是从AZ后跟一个O
  • \\1一个字符所捕获的字符从AZ
  • \\10是捕获的字符后跟一个0
+0

谢谢!而已!! – 2014-12-03 03:18:55

+1

不客气。请考虑通过点击旁边的勾号来接受您选择的答案。 – flodel 2015-01-05 01:53:23

2

如果格式总是这样,那么可以使用gsub来替换错误的“O”字符。

x <- c('A1A1A1', 'AOAOAO', 'A0B0CO', 'AOBOC0') 
gsub('[A-Z]\\KO', '0', x, perl=T) 
# [1] "A1A1A1" "A0A0A0" "A0B0C0" "A0B0C0" 
2

1)使用gsubfn,我们可以用特别简单的正则表达式做到这一点。请注意,gsubfn允许使用公式表示法指定第二个参数中的函数。这被视为xy与指示体的功能:

library(gsubfn) 
gsubfn("(.)(.)", ~ paste0(x, chartr("O", "0", y)), "O0OO1A") 
## [1] "O0O01A" 

注意这与位置和数值位置之前,不依赖于该位置的一封信所以它的工作原理,即使之前字母被错误地编码为数字,例如哦,为零。

2)以上很容易概括为将偶数位置的零到零和奇数位置的零到零。正则表达式保持不变,只在第二个参数的变化指定的功能:

ohzero <- function(x, y) paste0(chartr("0", "O", x), chartr("O", "0", y)) 
gsubfn("(.)(.)", ohzero, "O00O1A") 
## [1] "O0O01A" 

3)或做加转换的人眼睛(I)和眼睛的人使用这个功能,而不是ohzero

function(x, y) paste0(chartr("01", "OI", x), chartr("OI", "01", y))