1

假设邮政编码采用 A0A 0AA 或 A0 0AA 的形式,其中 A 是任何字母,0 是任何数字,我编写了以下 sed 脚本来搜索网页以查找邮政编码。

s/\(([[:alnum:]]\{2,4\})\) \(([[:alnum:]]\{3\})\)/\1 \2/p

将第一部分 (A0A) 存储在第一区域,将第二部分 (0AA) 存储在第二区域。然后打印出找到的内容。但是,运行此当前未找到任何邮政编码。

有任何想法吗?谢谢

4

3 回答 3

2

我意识到您在询问有效邮政编码的子集,但我希望这个英国邮政编码的解决方案会有所帮助。我会这样处理问题:

查看post-codes的格式,格式是

  • A9 9AA
  • A99 9AA
  • AA9 9AA
  • AA99 9AA
  • A9A 9AA
  • AA9A 9AA

最后一部分的正则表达式很简单:[0-9][A-Z]{2}

第一部分是骗人的。我将问题一分为二:

  • 上面的前四种模式可以使用 来匹配[A-Z]{1,2}[0-9]{1,2},即一个或两个字母后跟一个或两个数字;
  • 最后两个模式可以使用 匹配[A-Z]{1,2}[0-9][A-Z],即一个或两个字母,然后是一个数字和一个字母。

把它们放在一起:

sed -rn 's/.*(([A-Z]{1,2}[0-9]{1,2}|[A-Z]{1,2}[0-9][A-Z]) [0-9][A-Z]{2}).*/\1/p'
于 2012-11-08T15:14:48.723 回答
0

用你的正则表达式很难找到正确的东西。

  1. 那里的内部未转义括号有什么用?因为它们是未转义的,所以它们实际上是匹配的。无论如何,它们毫无用处。
  2. 当您的实际模式在某些地方需要[:alpha:]而在其他地方需要 [: digit :] 时,为什么要尝试匹配两个[:alnum:]块?
  3. 为什么是{2,4}?你想要两个或三个,而不是两个、三个或四个。你真正想要的是字母数字字母或字母数字。
  4. 因为您没有指定单词边界,所以即使您修复了正则表达式,第一个模式将匹配单词末尾的A0 ,而第二个模式将匹配单词开头的0AA 。

你至少需要

  1. 去掉内括号
  2. 将{2,4}更改为{2,3}
  3. 在正则表达式的开头和结尾添加单词边界匹配

但是,这仍然不能正确满足您的要求。它将匹配无效模式。你真正需要做的是

  1. 去掉内括号
  2. 更改第一个模式以匹配[:alpha:][:digit:][:alpha:][:digit:][:alpha:](有两种方法可以做到这一点)。
  3. 更改第二个模式以匹配[:digit:][:alpha:][:alpha:]
  4. 在正则表达式的开头和结尾添加单词边界匹配。

我没有给出如何做到这一点的具体例子,因为你要求“任何想法”。我假设你想尝试自己解决这个问题,给出正确的指示。

于 2012-11-08T14:26:30.593 回答
0

看起来你的括号有问题。以下对我有用:

$ sed -n 's/.*\b\([[:alnum:]]\{2,3\}\) \([[:alnum:]]\{3\}\)\b.*/\1 \2/p' <<< "here is a postcode: A0A 0AA. some more text"
A0A 0AA
于 2012-11-08T14:41:37.190 回答