【问题标题】:Extract all cell references in excel with regex in java使用java中的正则表达式提取excel中的所有单元格引用
【发布时间】:2014-03-03 05:35:02
【问题描述】:

拥有 excel 数据和公式,例如:

  • (S10+S14+S18+S22+S26+S30+S34)
  • E10+E11+SUM(E10;E14:E17)*E18-IF(E19
  • SUM(E14:E19)
  • S16*S15

等等。

我想从字符串中获取所有单元格引用。 就像在这个例子中:“E10+E11+SUM(E10;E14:E17)*E18-IF(E19

我想要像“E10 E11 ... E21”这样的输出子字符串或用“,”分隔。

我使用正则表达式进行了很多测试,但无法获得有效结果。 我正在使用此代码:

String formulaString = "E10+E11+SUM(E10;E14:E17)*E18-IF(E19<1,E20, E21)";
Pattern pattern = Pattern.compile("REGEX");
Matcher matcher = pattern.matcher(formulaString);

我尝试了以下正则表达式:

http://social.msdn.microsoft.com/Forums/en-US/815e819c-f0f2-4a53-8407-98b0f7f116e2/regex-to-extract-list-of-cell-references-from-excel-formula?forum=csharpgeneral

正则表达式:(\w+|)?\$?(?:\bXF[A-D]|X[A-E][A-Z]|[A-W][A-Z]{2}|[A-Z]{2}|[A-Z ])\$?(?:104857[0-6]|10485[0-6]\d|1048[0-4]\d{2}|104[0-7]\d{3}|10[ 0-3]\d{4}|[1-9]\d{1,5}|[1-9])d?\b(:\s?\$?(?:\bXF[A-D]| X[A-E][A-Z]|[A-W][A-Z]{2}|[A-Z]{2}|[A-Z])\$?(?:104857[0-6]|10485[0-6]\d |1048[0-4]\d{2}|104[0-7]\d{3}|10[0-3]\d{4}|[1-9]\d{1,5}| [1-9])d?\b)?

http://social.msdn.microsoft.com/Forums/en-US/dc179984-4fc8-4346-90e8-1649a23b6afe/regex-solution-to-id-excel-cell-references-in-an-excel-formula-string?forum=regexp

正则表达式:\$?\b([A-Z]|[A-H][A-Z]|I[A-V])\$?([1-9]\d{0,3}|[1-5]\ d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-6])\b([: \s]\$?\b([A-Z]|[A-H][A-Z]|I[A-V])\$?([1-9]\d{0,3}|[1-5]\d{ 4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-6])\b)?

对于某些公式,他们正在工作,但不是对所有的。

我希望任何人都可以帮助我或给我一个提示:)

【问题讨论】:

    标签: java regex excel substring excel-formula


    【解决方案1】:
    public static void main(String[]args){
    String formula = "E10+E11+SUM(E10;E14:E17)*E18-IF(E19<1,E20, E21)";
    String output="";
    
    
    for(String c: formula.split("[^A-z0-9]+")){
        if(isCell(c)){
                   output+=c+" ";
        }
    }
    
    
    }
    
    private static boolean isCell(String current){
       boolean hasLetter = false;
       boolean hasNumber = false;
    
    for(int i=0; i<current.length() && (!hasLetter || !hasNumber); i++){
    
    
        if(current.charAt(i)>=65 && current.charAt(i)<=90){
    
    
            hasLetter=true;
        }
        else if(current.charAt(i)>='0' && current.charAt(i)<='9'){
    
            hasNumber=true;
        }
    }
    
    return hasLetter && hasNumber;
    }
    

    【讨论】:

    • 不是一个好的答案。有些函数名称可能会与单元格字母混淆(例如 SUM),并且您的代码也没有考虑单元格编号(例如,它应该返回 E10 而不仅仅是 E)。
    • 答案与问题不符。但无论如何,谢谢..也许我可以通过正则表达式拆分更容易得到答案......我会尝试一下。
    • 我很抱歉。我忘记了数字。我已经编辑了答案以包含数字。
    • @Solace 这样更好,但它仍然没有解决我提到的另一个问题-您需要考虑内置函数,例如Yr1990()
    • 或许OP可以写一个函数来检查当前String是否是一个单元格。
    【解决方案2】:

    在您链接到的第一个线程上,您在链接下方放置的正则表达式在页面上找不到。你真的使用了那个页面的正则表达式吗?建议的正则表达式是:

    (\w+|)?\$?(?:\bXF[A-D]|X[A-E][A-Z]|[A-W][A-Z]{2}|[A-Z]{2}|[A-Z])\$?(?:104857[0-6]|10485[0-6]\d|1048[0-4]\d{2}|104[0-7]\d{3}|10[0-3]\d{4}|[1-9]\d{1,5}|[1-9])d?\b(:\s?\$?(?:\bXF[A-D]|X[A-E][A-Z]|[A-W][A-Z]{2}|[A-Z]{2}|[A-Z])\$?(?:104857[0-6]|10485[0-6]\d|1048[0-4]\d{2}|104[0-7]\d{3}|10[0-3]\d{4}|[1-9]\d{1,5}|[1-9])d?\b)?
    

    试试看。

    此外,了解哪些特定字符串没有正确匹配会有所帮助,因为您提到其中一些字符串有效。

    【讨论】:

    • 感谢您的回答。也许我错过了复制和粘贴的内容......但我已经尝试了你提供的字符串。使用此字符串,以下测试数据正在工作: S16*S15 和 E10+E11+SUM(E10;E14:E17)*E18-IF(E19
    • @user3373589 但是哪些字符串不起作用
    • 例如 (S10+S14+S18+S22+S26+S30+S34) 和 SUM(E14:E19)
    猜你喜欢
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-26
    • 2019-06-05
    相关资源
    最近更新 更多