2008-10-06 15 views
10

que necesita ser capaz de validar una cadena con una lista de las abreviaturas de los estados posibles del Servicio Postal de los Estados Unidos, y Google no me está ofreciendo cualquier dirección.Validar cadena contra USPS abreviaturas Estado

Conozco la solución obvia: y eso es codificar una horrible declaración if (o cambio) para verificar y comparar contra los 50 estados, pero estoy pidiendo StackOverflow, ya que tiene que haber una manera más fácil de hacerlo esta. ¿Hay algún objeto RegEx o enumerador que pueda usar para hacer esto de la forma más eficiente posible?

[C# y .NET 3.5 por cierto]

List of USPS State Abbreviations

+1

Por cierto, varios de esos "estados" son ahora los países independientes. Estados Federados de Micronesia, Islas Marshall, y uno o dos de esos grupos de islas del Pacífico. – Craig

Respuesta

18

me gusta algo como esto:

private static String states = "|AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY|"; 

public static bool isStateAbbreviation (String state) 
{ 
    return state.Length == 2 && states.IndexOf(state) > 0; 
} 

Este método tiene la ventaja de utilizar una rutina de sistema optimizado que probablemente está utilizando una sola máquina instrucciones para hacer la búsqueda. Si tuviera que lidiar con palabras de longitud no fija, buscaría "|" + estado + "|" para asegurarme de no haber golpeado una subcadena en lugar de una coincidencia completa. Eso llevaría un poco más de tiempo, debido a la concatenación de cadenas, pero aún coincidiría en un período de tiempo fijo. Si desea validar abreviaturas en minúsculas así como mayúsculas, entonces verifique state.UpperCase(), o duplique la cadena 'states' para incluir las variantes en minúsculas.

voy a garantizar que este le ganará a la expresión regular o Hashtable búsquedas cada vez, no importa cuántas carreras que gana, y tendrá el uso de menos memoria.

+0

¿Qué sucede si el usuario logra ingresar "L |" como su entrada? Me imagino que validaría bajo este código. Se puede arreglar fácilmente con una línea IndexOf ("|"). –

+1

Nuevamente, si está preocupado, es cuando concatenan los delimitadores alrededor de la cadena de búsqueda. Por lo tanto, estaría buscando "| L ||", que no funcionaría. –

3

He aquí una expresión regular. ¡Disfrutar!

^(?-i:A[LKSZRAEP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$ 
+2

Apoyos en una expresión regular genial, pero eso es simplemente ridículo. No creo que la expresión regular sea el camino a seguir; es extremadamente difícil de verificar con el ojo y cualquier prueba que escriba para verificar que funcione probablemente sea peor que solo implementarla de una manera más clara en primer lugar. –

+1

Algunas personas, cuando se enfrentan con un problema, piensan "Lo sé, usaré expresiones regulares". Ahora tienen dos problemas. - Jamie Zawinski. –

+0

Solo un aviso: esta expresión regular incluye varias abreviaturas no comúnmente consideradas, como Puerto Rico, Islas Marianas del Norte, Palau y las Islas Marshall. – hughdbrown

15

Me rellenar una tabla hash con abreviaturas válidos y después comprobar que con la entrada para su validación. Es mucho más limpio y probablemente más rápido si tiene más de un control por compilación de diccionario.

+0

Votado para una solución limpia y rápida. Tómese un tiempo de diseño y repare en tiempo de ejecución. – Craig

+0

Gracias por aclarar los genéricos específicos, Jon. –

8

Un HashSet < cadena> es la manera más limpia que puedo pensar en utilizar el incorporado en los tipos de .NET 3.5. (También podría hacerlo fácilmente insensible a mayúsculas y minúsculas o cambiarlo a una cadena de diccionario <, cadena > donde el valor es el nombre completo. Esa también sería la solución más adecuada para .NET 2.0/3.0.)

En cuanto a la velocidad, ¿realmente cree que esto será un cuello de botella en su código? Es probable que un HashSet funcione "bastante bien" (muchos millones de búsquedas por segundo). Estoy seguro de que las alternativas serían incluso más rápidas, pero más sucias. Me limitaría a lo más simple que funciona hasta que tengas razones para creer que será un cuello de botella.

(Editado mencionar explícitamente Diccionario <,>.)

Cuestiones relacionadas