java—用于浮点数范围的正则表达式生成器

ee7vknir  于 2021-08-25  发布在  Java
关注(0)|答案(0)|浏览(203)

我正在处理一个需求,我必须根据给定的范围生成正则表达式。通过用户输入,范围可以像任何东西一样
0-7
1-3456
0.5-15.7
122.56-150.55
对于这个范围,我需要一个正则表达式来匹配另一个值
例如:123.50应该与范围为122.56-150.55的正则表达式匹配
我在java中发现了一个类似于此的解决方案,但适用于数字范围https://stackoverflow.com/a/57474599/16396074

protected String[] regexArray = null;
protected List<String> regexList = null;

public static void main (String[] args) throws java.lang.Exception
{
    Ideone ideone = new Ideone();
    ideone.generateRegEx("287", "2678905");
    for (String s: ideone.regexArray) { System.out.println(s); }
}
public Ideone()
{
    regexList = new ArrayList<String>();
}   
/**

* Return a list of regular expressions that match the numbers
* that fall within the range of the given numbers, inclusive.
* Assumes the given strings are numbers of the the same length,
* and 0-left-pads the resulting expressions, if necessary, to the
* same length.
* @param begStr
* @param endStr
* /

public void generateRegEx(String begStr, String endStr)
{

    //Log Input Data.
    System.out.println("Starting getRegex Method with String input.");
    System.out.println("Input Data is: ");
    System.out.println("Range Start       : [" + begStr + "]");
    System.out.println("Range End         : [" + endStr + "]");

    //Get integer range values.
    System.out.println("Converting input string range values to integer values.");

    int beg = Integer.parseInt(begStr);
    int end   = Integer.parseInt(endStr);

    System.out.println("Successfully converted input string range values to integer values.");

    //Print integer values
    System.out.println("Range Start (Int) : [" + beg + "]");
    System.out.println("Range End   (Int) : [" + end + "]");            

    //call common method to generate RegEx Pairs.
    generateRegExCommon(beg,end,begStr.length());

}

/**

* Return a list of regular expressions that match the numbers
* that fall within the range of the given numbers, inclusive.
* @param beg
* @param end
* 
**/

public void generateRegEx(int beg, int end)
{

    //Log Input Data.
    System.out.println("Starting getRegex Method with integer input.");
    System.out.println("Input Data is: ");
    System.out.println("Range Start       : [" + beg + "]");
    System.out.println("Range End         : [" + end + "]");

    //call common method to generate RegEx Pairs.
    generateRegExCommon(beg,end,0);     
}

private void generateRegExCommon(int start, int end, int stringLength)
{
    //call method to generate RegEx Pairs.
    System.out.println("Calling method to generate RegEx pairs for the input.");

    List<Integer> pairs = getRegexPairsRecursion(start, end, 1);

    System.out.println("Returned from method with a List of RegEx pairs for the input.");
    System.out.println("Total RegEx Ranges: [" + pairs.size()/2 + "]");

    System.out.println("Printing range values.");
    pairs.forEach(s-> System.out.println(s+""));
    System.out.println("Completed printing range values.");

    printPairList(pairs);

    //String length of the input is used to identify if any leading zeros need to be prepended to the RegEx pairs.
    System.out.println("String length of input is: [" + stringLength + "]");

    System.out.println("Calling method to convert range pairs to RegEx.");              
    //regexList = toRegex(pairs, stringLength);
    regexList = formatPairsToRegEx(pairs, stringLength);
    System.out.println("Completed converting range pairs to RegEx.");

    System.out.println("Printing RegEx list.");
    regexList.forEach(s-> System.out.println(s+""));
    System.out.println("Completed printing RegEx list.");

    System.out.println("Converting RegEx list to an array.");   
    regexArray = regexList.toArray(new String[regexList.size()]);
    System.out.println("Completed converting RegEx list to an array.");

    System.out.println("Printing RegEx array.");
    regexList.forEach(s-> System.out.println(s+""));
    System.out.println("Completed printing RegEx array.");              
}

  /**
   * return the list of integers that are the paired integers
   * used to generate the regular expressions for the given
   * range. Each pair of integers in the list -- 0,1, then 2,3,
   * etc., represents a range for which a single regular expression
   * is generated.
   * @param start
   * @param end
   * @return
   */
  private List<Integer> getRegexPairsRecursion(int start, int end, int recursionLevel)
  {     
    List<Integer> pairs = null;

    pairs = new ArrayList<>();
    String printIndent = "";

    for (int i = 0; i <= recursionLevel - 1; i++) 
    {
        printIndent += "  ";
    }

    System.out.println(printIndent + "Entering method " + "getRegexPairsRecursion." + " Level [" + recursionLevel + "].");

    System.out.println(printIndent + "Start Range       : [" + start + "]");
    System.out.println(printIndent + "End Range         : [" + end + "]");

    if(start == 0)
    {
        System.out.println(printIndent + "Range start value is 0. Add pair of zeros and set start range value to 1.");
        pairs.add(0);
        pairs.add(0);
        start = 1;
    }

    /*If start is greater than end of the range, return the current values in pairs.
     * Apart from the special case when start value is 0, this will always be empty,
     *because if start is greater than end range value, it cannot be represented using
     *RegEx range.
     */
    if (start > end) 
    {
        System.out.println(printIndent + "Return as start value is greater than end.");

        System.out.println(printIndent + "Exit method " + "getRegexPairsRecursion." + " Level [" + recursionLevel + "].");          
        return pairs;
    }

    /* 
     * Calculate first number ending with 0, which is greater than the start value.
     * This will tell us whether or not start and end values differ only at last digit.     
     */
    int firstEndingWith0 = 10*((start+9)/10);
    System.out.println(printIndent + "First number ending with 0 which is greater than start number [" + start + "] is: ["+ firstEndingWith0 +"]");

    /* 
     * Start and end values differ only at the last digit.
     */
    if (firstEndingWith0 > end) // not in range?
    {
        System.out.println(printIndent + "Start and end only differ at the last digit, no further processing needed.");

        pairs.add(start);
        pairs.add(end);

        System.out.println(printIndent + "Exit method " + "getRegexPairsRecursion." + " Level [" + recursionLevel + "].");          
        return pairs;
    }

    /* 
     * start is not ending in 0.
     */     
    if (start < firstEndingWith0) 
    {
        System.out.println(printIndent + "Start Range i.e. ["+ start +"] does not end in 0. Add the numbers ["+start+"] and [" + (firstEndingWith0 - 1) +"], to list.");            
        pairs.add(start);
        pairs.add(firstEndingWith0-1);
    }

    //Largest number ending with 9, which is smaller than the Range end.
    int lastEndingWith9 = 10*(end/10)-1;
    System.out.println(printIndent + "Last number in range, which ends with 9 is: ["+ lastEndingWith9 +"]");

    System.out.println(printIndent + "New Working Range is ["+ firstEndingWith0 + " - " + lastEndingWith9 + "].");          

    System.out.println(printIndent + "Call Recursion with Range ["+ (firstEndingWith0/10) + " - " + (lastEndingWith9/10) + "].");           

    /*
     *  All RegEx for the range [firstEndingWith0,lastEndingWith9] end with [0-9],
     *  hence, remove the rightmost 0 from new working range start and remove the rightmost
     *  9 from new working range end.
     */
    List<Integer> pairsMiddle = getRegexPairsRecursion(firstEndingWith0/10, lastEndingWith9/10, recursionLevel+1);

    System.out.println(printIndent + "Returned From Recursion ["+ firstEndingWith0/10 + " - " + lastEndingWith9/10 + "]."); 

    System.out.println(printIndent + "Printing results from this call.");   

    for(int j = 0; j<pairsMiddle.size(); j++)
    {
        System.out.println(printIndent + "" + pairsMiddle.get(j));          
    }

    /*
     * Append digits to start and end of each pair. 0 will be appended to the low value of
     * the pair and 9 will be appended to the high value of the pair.
     * This is equivalent of multiplying low value by 10, and multiplying high value by 10
     * and adding 9 to it.
     */

    if(pairsMiddle.size() > 0)
    {   
        System.out.println(printIndent + "Append digits to the generated pair(s).");                    
    }
    for (int i=0; i<pairsMiddle.size(); i+=2)
    {
        System.out.println(printIndent + pairsMiddle.get(i)   + " --> " + (pairsMiddle.get(i)  *10+0));
        System.out.println(printIndent + pairsMiddle.get(i+1) + " --> " + (pairsMiddle.get(i+1)*10+9));
        pairs.add(pairsMiddle.get(i)  *10+0);
        pairs.add(pairsMiddle.get(i+1)*10+9);
    }

    System.out.println(printIndent + "Printing the current list of pairs."); 
    for(int j = 0; j<pairs.size(); j++)
    {
        System.out.println(printIndent + "" + pairs.get(j));            
    }

    if (lastEndingWith9 < end) // end is not ending in 9
    {
      System.out.println(printIndent + "Range end [" + end + "] is greater than last number in current pair list [" + lastEndingWith9 + "]");
      System.out.println(printIndent + "Add ["+ (lastEndingWith9+1) + "] and [" + end + "] to the list.");
      pairs.add(lastEndingWith9+1);
      pairs.add(end);
    }

    System.out.println(printIndent + "Exit method " + "getRegexPairsRecursion." + " Level [" + recursionLevel + "].");      
    return pairs;
  }

  /**
   * print the given list of integer pairs - used for debugging.
   * @param list
   */
  private void printPairList(List<Integer> list)
  {
    if (list.size() > 0)
    {
      System.out.println("Printing pair values of start and end as hyphen separated list.");                                
      System.out.println(String.format("%d-%d", list.get(0), list.get(1)));       
      int i = 2;
      while (i < list.size())
      {
        System.out.println(String.format("%d-%d", list.get(i), list.get(i + 1)));
        i = i + 2;
      }
    }
  }
  /**
   * return the regular expressions that match the ranges in the given
   * list of integers. The list is in the form firstRangeStart, firstRangeEnd, 
   * secondRangeStart, secondRangeEnd, etc. Each regular expression is 0-left-padded,
   * if necessary, to match strings of the given width.
   * @param pairs
   * @param minWidth
   * @return
   */
  private List<String> formatPairsToRegEx(List<Integer> pairs, int minWidth)
  {
    List<String> list = null;
    list = new ArrayList<>();
    String numberWithWidth = String.format("%%0%dd", minWidth);
    for (Iterator<Integer> iterator = pairs.iterator(); iterator.hasNext();)
    {
      String start = String.format(numberWithWidth, iterator.next());
      String end = String.format(numberWithWidth, iterator.next());

        assert start.length() == end.length();

        StringBuilder result = new StringBuilder();

        for (int pos = 0; pos < start.length(); pos++)
        {
          if (start.charAt(pos) == end.charAt(pos))
          {
            result.append(start.charAt(pos));
          } else
          {
            result.append('[').append(start.charAt(pos)).append('-')
                .append(end.charAt(pos)).append(']');
          }
        }

      list.add(result.toString());
    }
    return list;
  }

我不是一个正则表达式Maven,但试图将此代码转换为支持浮点数以及java中的任何帮助都将不胜感激。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题