Question

Je dois reformater une liste des codes postaux du Royaume-Uni et ont commencé avec les éléments suivants pour dépouiller les espaces et tirer parti:

postcode.upcase.gsub(/\s/,'')

Je dois maintenant changer le code postal de sorte que le nouveau code postal sera dans un format qui correspondra à l'expression rationnelle suivante:

^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$

Je vous serais reconnaissant de toute aide.

Était-ce utile?

La solution

Si cette doc normes est à croire (et Wikipedia Souscrit ), le formatage d'un code postal valide pour la sortie est simple: les trois derniers caractères sont la deuxième partie, tout est avant la première partie!

supposant que vous avez un code postal valide, sans espace pré-intégré, il vous suffit

def format_post_code(pc)
  pc.strip.sub(/([A-Z0-9]+)([A-Z0-9]{3})/, '\1 \2')
end

Si vous voulez valider un code postal d'entrée, puis l'expression régulière que vous avez donné ressemble à un bon point de départ. Peut-être quelque chose comme ça?

NORMAL_POSTCODE_RE = /^([A-PR-UWYZ][A-HK-Y0-9][A-HJKS-UW0-9]?[A-HJKS-UW0-9]?)\s*([0-9][ABD-HJLN-UW-Z]{2})$/i
GIROBANK_POSTCODE_RE = /^GIR\s*0AA$/i
def format_post_code(pc)
  return pc.strip.upcase.sub(NORMAL_POSTCODE_RE, '\1 \2') if pc =~ NORMAL_POSTCODE_RE
  return 'GIR 0AA' if pc =~ GIROBANK_POSTCODE_RE
end

Notez que j'ai enlevé la partie « 0-9 » du premier caractère, qui ne paraît pas nécessaire selon les sources que je viens de citer. J'ai aussi changé l'alpha fixe pour correspondre à la première cité document. Il est pas encore parfait. Un code de format valide les « AAA ANN », par exemple, et je pense qu'un RE plus complexe est probablement nécessaire

Je pense que cela pourrait couvrir (construit par étapes pour faciliter la fixation!)

A1  = "[A-PR-UWYZ]"
A2  = "[A-HK-Y]"
A34 = "[A-HJKS-UW]"        # assume rule for alpha in fourth char is same as for third
A5  = "[ABD-HJLN-UW-Z]"
N   = "[0-9]"
AANN = A1 + A2 + N + N     # the six possible first-part combos
AANA = A1 + A2 + N + A34
ANA  = A1 + N + A34
ANN  = A1 + N + N
AAN  = A1 + A2 + N
AN   = A1 + N
PART_ONE = [AANN, AANA, ANA, ANN, AAN, AN].join('|') 
PART_TWO = N + A5 + A5

NORMAL_POSTCODE_RE = Regexp.new("^(#{PART_ONE})[ ]*(#{PART_TWO})$", Regexp::IGNORECASE)  

Autres conseils

Royaume-Uni Les codes postaux ne sont pas compatibles, mais ils sont finis -. Vous pourriez être mieux avec une table de correspondance

reformater ou correspondance de motif? Je soupçonne que ce dernier, bien que upcasing il est d'abord une bonne idée.

Avant d'aller si je vous signale que vous Décapage des espaces, mais votre regex contient « {1,2} » qui est « un ou deux caractères de l'espace ». Comme vous l'avez déjà dépouillé des espaces que vous avez déjà fait tout échouer le match.

Étant donné un code postal en entrée, nous pouvons vérifier si elle correspond à l'expression régulière en utilisant = ~

Ici, nous créons des codes postaux (exemple pris de la wikipedia ), et le test chacun contre l'expression rationnelle:

post_codes = ["M1 1AA", "M60 1NW", "CR2 6XH", "DN55 1PT", "W1A 1HQ", "EC1A 1BB", "bad one", "cc93h29r2"]
r = /^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$/

post_codes.each do |pc|
  # pc =~ r will return something true if we have a match (specifically the integer of first match position)
  # We use !! to display it as true|false
  puts "#{pc}: #{!!(pc =~ r)}"
end
M1 1AA: true
M60 1NW: true
CR2 6XH: true
DN55 1PT: true
W1A 1HQ: true
EC1A 1BB: true
bad one: false
cc93h29r2: false
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top