2012-01-11 6 views
1

Как проверить, подходит ли строка в формате:Строка содержит три запятых номера?

<number>,<number>,<number> 

например

3.0, 87546,0.8273456 

т. Е. Три значения, разделенные запятой, которые могут обрабатываться как удвоенные. Иногда строка будет содержать что-то еще (например, Text,More text,42 или anything, really), и в этом случае мне просто нужно проигнорировать ее и перейти к разбору следующей строки.

Прямо сейчас я просто пытаюсь разобрать строку так, как если бы она соответствовала ожидаемому формату, и поймать любое полученное исключение. Что является более умным и менее дорогостоящим способом? Надеюсь, не выбрасывать/ловить исключения?

 String[] parsedLine = line.trim().split(","); 
     if (parsedLine.length == 3) { 
      try { 
       xCoordinate = Double.parseDouble(parsedLine[0]); 
       yCoordinate = Double.parseDouble(parsedLine[1]); 
       groundElevation = Double.parseDouble(parsedLine[2]); 
      } catch (NumberFormatException nfe) { 
       //This line does not contain numbers exclusively. 
       //Assume it's a header/comment. 
       //Do nothing. 
      } 
     } else { 
      //This is not in the expected x,y,z format. 
      //Assume it's a header/comment. 
      //Do nothing. 
     } 
+0

Помните, что вам необходимо правильно обработать следующее: '1," текст, 1.5 ", 2'. – Vlad

+0

im не java-программист, но как насчет использования 'try {int [] parsedLine = line.trim(). Split (", ");} catch {// Not numbers}' – Dementic

+0

@Dementic: действительно, вы а не Java-программистом. int и String - два разных типа в Java, и вы не можете просто притворяться, что String [] - это int []. И блок catch нуждается в исключении. –

ответ

2

То, что вы сейчас, вероятно, является наиболее пуленепробиваемые (и, на мой взгляд, легче понять) осуществление возможно.

Я бы не изменил его, если у меня не было конкретных доказательств от профайлера о том, что это общее узкое место (либо с точки зрения использования ЦП, либо количества созданного мусора).

+0

Как я спросил JB Nizet: Но разве исключения не должны использоваться только в исключительных условиях? Здесь я использую их, как само собой разумеющееся. –

+1

@ Jean-FrançoisCorbett: У меня лично нет таких возражений против использования исключений. Задайте себе это: * каковы конкретные конкретные причины, почему следует избегать использования исключений таким образом? * – NPE

1

Нет чистых способов. Ваш код в порядке.

Вы спрашиваете: «Но не следует исключений» использовать только в исключительных условиях »? Здесь я использую их, как само собой разумеющееся».

Ну, в Java нет никакого метода Double.isValid(String). Если бы это было, вы могли бы использовать его, но это не так. И даже тогда вам придется разобрать двойной дважды: один раз, чтобы проверить, является ли он двойным, и один раз, чтобы получить двойное значение.

У вас есть распространенная идиома, и я сомневаюсь, что регулярные выражения будут более читабельными и быстрыми, чем то, что у вас есть.

+1

Но разве исключения не должны использоваться только в исключительных условиях? Здесь я использую их, как само собой разумеющееся. –

+2

Кроме того, Java не имеет метода Double.isValid (String). Если бы это было, вы могли бы использовать его, но это не так. И даже тогда вам придется разобрать двойной дважды: один раз, чтобы проверить, является ли он двойным, и один раз, чтобы получить двойное значение. У вас есть распространенная идиома, и я сомневаюсь, что регулярные выражения будут более читабельными и быстрыми, чем у вас. –

+0

Не уверен, что я согласен с этим ответом. Предполагается, что исключения относятся к случаям с «ошибкой» и к тем, что не происходит при обычном прогоне обработки. Я считаю, что перед обработкой лучше очищать входные данные от какого-то регулярного выражения - сложная часть состоит в том, чтобы точно определить, что должно быть в этом регулярном выражении. Это было бы отличным упражнением для оригинального плаката. –

0

Вы можете использовать regex \ d для цифр. так что-то вроде этого

\ d + \ d + \ d +

жаль непроверенных :)

+0

Этот конкретный шаблон будет соответствовать строкам «,,» и «1,2,3», если требуются десятичные числа. – Peter

+0

Вы правы, это должно быть \ d + я отредактирую свой ответ – dbrin

0

Используйте это регулярное выражение по всему тексту Это предполагает, что не будет никакого пространства между числами и запятыми, вы можете внести соответствующие изменения, чтобы добавить дополнительные космические символы

[0-9]+(\.[0-9]*)?,[0-9]+(\.[0-9]*)?,[0-9]+(\.[0-9]*)? 

Я просто сделал изменения

[0-9]+(\.[0-9]*)?\s*,\s*[0-9]+(\.[0-9]*)?\s*,\s*[0-9]+(\.[0-9]*)? 

Это будет пространство дружественным Из курса вы должны проверить это, хотя

2

Я думаю, что это не так дорогая. String.split() создаст Pattern по вашему параметру и разделит вокруг него строку.

Если вы беспокоиться о стоимости исключений, то можно создать более сложную структуру, чтобы соответствовать вашей строке, и вы, вероятно, не будете иметь их:

final Pattern pattern = Pattern.compile("^(\\d+(\\.\\d+)?),(\\d+(\\.\\d+)?),(\\d+(\\.\\d+)?)$"); 
final Matcher matcher = pattern.matcher(line); 
if (matcher.matches()) { 
    xCoordinate = Double.parseDouble(matcher.group(1)); 
    // ... 
} 
1

Вы можете использовать регулярное выражение для двойников от here:

public boolean matches(String str) { 
    final String Digits  = "(\\p{Digit}+)"; 
    final String HexDigits = "(\\p{XDigit}+)"; 
    final String Exp  = "[eE][+-]?"+Digits; 
    final String fpRegex = 
      ("[\\x00-\\x20]*"+ // Optional leading "whitespace" 
        "[+-]?(" + // Optional sign character 
        "NaN|" +   // "NaN" string 
        "Infinity|" +  // "Infinity" string 

        // A decimal floating-point string representing a finite positive 
        // number without a leading sign has at most five basic pieces: 
        // Digits . Digits ExponentPart FloatTypeSuffix 
        // 
        // Since this method allows integer-only strings as input 
        // in addition to strings of floating-point literals, the 
        // two sub-patterns below are simplifications of the grammar 
        // productions from the Java Language Specification, 2nd 
        // edition, section 3.10.2. 

        // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt 
        "((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+ 

        // . Digits ExponentPart_opt FloatTypeSuffix_opt 
        "(\\.("+Digits+")("+Exp+")?)|"+ 

        // Hexadecimal strings 
        "((" + 
        // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt 
        "(0[xX]" + HexDigits + "(\\.)?)|" + 

        // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt 
        "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" + 

        ")[pP][+-]?" + Digits + "))" + 
        "[fFdD]?))" + 
        "[\\x00-\\x20]*");// Optional trailing "whitespace" 

    String pattern=fpRegex + "," + fpRegex + "," + fpRegex; 
    return str.matches(pattern); 
} 
+0

Возможно, здесь не требуются опции для шестнадцатеричных, экспонентов и конечных fFdD. Я бы пошел с чем-то вроде ответа KARASZI Istvan, плюс пробелы до и после каждого скобочного фрагмента. Это имеет дополнительное преимущество, которое вы можете выполнять итерацией через 'matcher', чтобы фактически получить номера. –

1

хорошее начало было бы использовать класс Узор: boolean b = Pattern.matches(".*,.*,.*", str); Однако, чтобы иметь номера там вы должны иметь более сложное регулярное выражение:

String str = "3.0,87546,0.8273456"; 
    boolean b = Pattern.matches("^(\\d+(\\.\\d+)?),(\\d+(\\.\\d+)?),(\\d+(\\.\\d+)?)$", str); 
    if (b) { 
     System.out.println("matches"); 
    } else { 
     System.out.println("does not match"); 
    } 

    // output: matches 

EDIT: Я вижу KARASZI уже бил меня по скорости, но тем не менее, код здесь ...

2

Регулярные выражения будет естественным решением этой проблемы. Я и многие другие сразу использовали бы этот подход. Однако в своем вопросе вы указываете, что ищете более дешевое решение. Регулярные выражения, вероятно, будут более дорогими с точки зрения используемых ресурсов.

В ответ на ваши комментарии «исключение не должно использоваться только в исключительных условиях», я бы сказал, что эта проблема является исключительным условием; Проблема, когда использование исключений таким образом создает более элегантное решение.

Ваше текущее решение прост, кратким и легким для понимания (следовательно, простым в обслуживании). Если это сработает, я не буду тратить время на его изменение.

Смежные вопросы