/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.nifi.attribute.expression.language.evaluation.util; import java.util.regex.Pattern; public class NumberParsing { public static enum ParseResultType { NOT_NUMBER, WHOLE_NUMBER, DECIMAL; } private static final String OptionalSign = "[\\-\\+]?"; private static final String Infinity = "(Infinity)"; private static final String NotANumber = "(NaN)"; // Base 10 private static final String Base10Digits = "\\d+"; private static final String Base10Decimal = "\\." + Base10Digits; private static final String OptionalBase10Decimal = Base10Decimal + "?"; private static final String Base10Exponent = "[eE]" + OptionalSign + Base10Digits; private static final String OptionalBase10Exponent = "(" + Base10Exponent + ")?"; // Hex private static final String HexIdentifier = "0[xX]"; private static final String HexDigits = "[0-9a-fA-F]+"; private static final String HexDecimal = "\\." + HexDigits; private static final String OptionalHexDecimal = HexDecimal + "?"; private static final String HexExponent = "[pP]" + OptionalSign + Base10Digits; private static final String OptionalHexExponent = "(" + HexExponent + ")?"; // Written according to the "Floating Point Literal" specification as outlined here: http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.2 private static final String doubleRegex = OptionalSign + "(" + Infinity + "|" + NotANumber + "|"+ "(" + Base10Digits + Base10Decimal + ")" + "|" + "(" + Base10Digits + OptionalBase10Decimal + Base10Exponent + ")" + "|" + "(" + Base10Decimal + OptionalBase10Exponent + ")" + "|" + // The case of a hex number with a decimal portion but no exponent is not supported by "parseDouble" and throws a NumberFormatException "(" + HexIdentifier + HexDigits + "\\.?" + HexExponent + ")" + "|" + // The case of a hex numeral with a "." but no decimal values is valid. "(" + HexIdentifier + HexDigits + OptionalHexDecimal + HexExponent + ")" + "|" + "(" + HexIdentifier + HexDecimal + OptionalHexExponent + ")" + ")"; private static final String numberRegex = OptionalSign + "(" + Base10Digits + "|" + HexIdentifier + HexDigits + ")"; private static final Pattern DOUBLE_PATTERN = Pattern.compile(doubleRegex); private static final Pattern NUMBER_PATTERN = Pattern.compile(numberRegex); private NumberParsing(){ } public static ParseResultType parse(String input){ if (NUMBER_PATTERN.matcher(input).matches()) { return ParseResultType.WHOLE_NUMBER; } else if (DOUBLE_PATTERN.matcher(input).matches()) { return ParseResultType.DECIMAL; } else { return ParseResultType.NOT_NUMBER; } } }