Номер дома парсинга


У меня есть 2 функции, используемые для анализа номер дома, и я думаю, что все это может быть улучшено.

Какие-либо предложения?

вход:

45a - 47b

или

45a bis 47b

выход:

45,a,47,b
public static string[] HausnummerAufteilen(string hausNummer)
    {
        string[] result = new string[4];
        string[] resultVon = new string[2];
        string[] resultBis = new string[2];

        resultVon[0]  = string.Empty;
        resultVon[1]  = string.Empty;
        resultBis[0]  = string.Empty;
        resultBis[1]  = string.Empty;           

        int pos1, pos2;
        pos2 = 0;
        pos1 = hausNummer.IndexOf("bis");
        if (pos1 != -1)
        { 
            pos2 = pos1 + 3;
        }
        else
        {
            pos1 = hausNummer.IndexOf("-");
            if (pos1 != -1)
                pos2 = pos1 + 1;
        }

        if (pos1 > 0)
        {
            resultVon = HausnummerBuchst(hausNummer.Substring(0, pos1).Trim());
            resultBis = HausnummerBuchst(hausNummer.Substring(pos2, hausNummer.Length - pos2).Trim());
        }
        else
            resultVon = HausnummerBuchst(hausNummer);


        List<string> list = new List<string>();
        list.AddRange(resultVon);
        list.AddRange(resultBis);
        result = list.ToArray();


        return result;
    }

    public static string[] HausnummerBuchst(string hauseNummer)
    {
        string[] result = new string[2];

        result[0] = string.Empty;
        result[1] = string.Empty;

        int iPos;
        int testInt;
        bool bFound = false;

        for (iPos = 0; iPos < hauseNummer.Length; iPos++)
        {

            if (!int.TryParse(hauseNummer[iPos].ToString() ,out testInt))
            {
                bFound = true;
                break;
            }
        }

        if (bFound)
        {
            result[0] = hauseNummer.Substring(0, iPos).Trim();
            result[1] = hauseNummer.Substring(iPos, hauseNummer.Length - iPos).Trim();
        }
        else
            result[0] = hauseNummer;            

        return result;

    }


2228
15
задан 1 февраля 2011 в 07:02 Источник Поделиться
Комментарии
1 ответ

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

Иногда после обследования выясняется, быть законным и мудрого использования. Однако очень часто программист вручную разделить строки и в цикле по части строки. Другими словами, они делают именно то, что строку.Сплит() и foreach для петель предложил бы их, но делать это дольше и менее читаемой.

Это один из тех случаев.

Это может быть просто мой личный вкус в код. В любом случае, я могу показать вам, как я буду решать эту проблему, используя конструкцию foreach и Сплит(), который я считаю, будет отличным улучшением для вашего метода. За исключением этого различия, я думаю, мы имели сопоставимые подходы.

Имена переменных

Много переменных называются очень мало описательности. Вы можете понять, что переменные названы так, что кто-то сохранения или считывания кода (такие как я) могут понять, что происходит, но вы могли сделать намного лучше в этом отделе.


  • результат: вы используете это слово много раз в именах переменных. Проблему это имя совершенно бесполезно для меня. Я вижу это результат чего-то (по-разному функция, петлей или каким-либо другим процессом), но за что вы могли бы также просто назвать переменную именем foo или бар. hauseNummerVon и hauseNummerBin гораздо более понятны, чем resultVon и resultBin - я теперь точно знаю, что это, это от дома № а до дома№.

    • Для результате[] массив, я остался ни с чем и мне придется прочитать весь код, прежде чем я понял, что они содержали. Это немного назад - я должен знать, что эта переменная содержит, тогда удастся прочитать код - с описательные имена переменных дает мне более глубокое понимание того, что происходит.


  • bFound: не сократить ваши имена переменных, как это. Я остался в недоумении: что это б? Что это значит если это нашли? Может быть, это будет более узнаваемым для немецкого читателя, но даже если и так, расширяя б слова, чтобы сказать именно то, что нашли бы для удобства чтения.

  • pos1, pos2: SeparatorPosition и SeparatorEnd было бы более описательным. Еще лучше эти переменные совершенно ненужным, если вы просто использовать строку.Сплит().

Мой подход

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

ParseHouseNumberRange

Это способ записи. Вы кормите этот метод строку, например "бис 20а 21в". Он разделяет его на "бис" или "-" (определенные в сепараторы массив) для того чтобы произвести более мелкие куски исходной строки.

Каждый из этих кусков передается затем проходит каждый из результатов (в данном случае "20а" и "21век", вместе с пробелами) в негосударственных способ ParseHouseNumber ниже. ParseHouseNumber будет разбить эти блоки дальше, и этот метод сочетает в себе все результаты в один массив, который возвращается.

Учитывая "бис 20а 21в" или подобный, она возвращает массив: 20, а 21, с.

public string[] ParseHouseNumberRange(string houseNumberRange)
{
string[] separators = new string[] {"bis", "-"};
string[] houseNumbers = houseNumberRange.Split(separators,
StringSplitOptions.RemoveEmptyEntries);

List<string> parsedList = new List<string>();

foreach (string houseNumber in houseNumbers)
{
parsedList.AddRange(ParseHouseNumber(houseNumber));
}

return parsedList.ToArray();
}

ParseHouseNumber

Этот метод занимает сегмент адрес из метода выше, такие как "20а ". После обрезки из любого места, он идет через строку посимвольно, выщипывание из цифр и букв и сортируя их в свои отдельные разделы, например, "1c4ad3" будет разделен на разделы 1, с, 4, объявление, 3. Любые нецифровые символы игнорируются.

Как только все секции были отсортированы из строки, предоставленной ему, он возвращает эти разделы в виде массива.

public string[] ParseHouseNumber(string houseNumber)
{
bool firstRun = true;
bool alphabeticMode = false; // set on first run

houseNumber = houseNumber.Trim();

List<string> sections = new List<string>();
string currentSection = "";

foreach (char c in houseNumber)
{
bool isLetter = Char.IsLetter(c);
bool isDigit = Char.IsDigit(c);

if (!(isDigit || isLetter)) continue;

// If we've switched character type, then a section's finished.
if (firstRun)
{
alphabeticMode = isLetter;
firstRun = false;
}
else if ((isLetter && !alphabeticMode)
|| (isDigit && alphabeticMode))
{
sections.Add(currentSection);
currentSection = "";
alphabeticMode = !alphabeticMode;
}

currentSection += c;
}

if (currentSection != "") sections.Add(currentSection);

return sections.ToArray();
}

22
ответ дан 1 февраля 2011 в 09:02 Источник Поделиться