【问题标题】:Parse groups from regex string?从正则表达式字符串解析组?
【发布时间】:2021-10-05 22:34:25
【问题描述】:

如果我有以下正则表达式字符串:

String one = "\"/^[^.]+$|\\.(?!(avi|bmp)$)([^.]+$)/i\"";
String two = "\"/^.*\\.(txt)$/i"";

假设我只想从字符串中解析出文件扩展名,例如,我想:

List<String> fileExtensionsOne = getFileExtensionsFromRegex(one); // Returns ("avi",bmp")
List<String> fileExtensionsTwo = getFileExtensionsFromRegex(two); // Returns ("txt")

实现getFileExtensionsFromRegex 的最佳方式是什么?是否可以将字符串转换为 Java Regex 对象并从中获取组?例如不将模式应用于某些输入文本?

编辑,我想我可以依靠正则表达式模式保持相当一致,要么是这样:

'/^.*\\.(' + _map(extensions, 'text').join('|') + ')$/i'

或者这个:

'/^[^.]+$|\\.(?!(' + _map(extensions, 'text').join('|') + ')$)([^.]+$)/i'

【问题讨论】:

  • 这些正则表达式模式中有多少是恒定的?单扩展的情况总是"\"/^.*\\.(ext)$/i"",两个扩展的情况总是"\"/^[^.]+$|\\.(?!(ext1|ext2)$)([^.]+$)/i\"",两个以上的扩展类似吗?我敢肯定,可以想出许多不同的正则表达式模式,它们都进行相同的文件扩展名匹配。你肯定不想写一个成熟的正则表达式分析器(除非你有几年的空闲时间)。
  • @RalfKleberhoff 为问题添加了更多信息 - 我认为模式将保持一致

标签: java regex parsing


【解决方案1】:

您的逻辑可以从比较每个字符开始,它是 ASCII 字母。这是一个快速的 ASCII 字符参考:

{
"31": "",      "32": " ",     "33": "!",     "34": "\"",    "35": 
"#",    
"36": "$",     "37": "%",     "38": "&",     "39": "'",     "40": 
"(",    
"41": ")",     "42": "*",     "43": "+",     "44": ",",     "45": 
 "-",    
"46": ".",     "47": "/",     "48": "0",     "49": "1",     "50": 
"2",    
"51": "3",     "52": "4",     "53": "5",     "54": "6",     "55": 
"7",    
"56": "8",     "57": "9",     "58": ":",     "59": ";",     "60": 
"<",    
"61": "=",     "62": ">",     "63": "?",     "64": "@",     "65": 
"A",    
"66": "B",     "67": "C",     "68": "D",     "69": "E",     "70": 
"F",    
"71": "G",     "72": "H",     "73": "I",     "74": "J",     "75": 

“K”,
“76”:“L”,“77”:“M”,“78”:“N”,“79”:“O”,“80”: "P",
“81”:“Q”,“82”:“R”,“83”:“S”,“84”:“T”,“85”: “U”,
“86”:“V”,“87”:“W”,“88”:“X”,“89”:“Y”,“90”: "Z",
“91”:“[”,“92”:“\”,“93”:“]”,“94”:“^”,“95”: "_",
“96”:“`”,“97”:“a”,“98”:“b”,“99”:“c”,
“100”:“d”,
“101”:“e”,“102”:“f”,“103”:“g”,“104”:“h”,
“105”:“我”,
“106”:“j”,“107”:“k”,“108”:“l”,“109”:“m”,
"110": "n",
“111”:“o”,“112”:“p”,“113”:“q”,“114”:“r”,
"115": "s",
“116”:“t”,“117”:“u”,“118”:“v”,“119”:“w”,
“120”:“x”,
“121”:“y”,“122”:“z”,“123”:“{”,“124”:“|”,
"125": "}",
“126”:“~”,“127”:“” }

类似的东西来自

String.fromCharCode(97) //will return 'a'

String.fromCharCode(122) //will return 'z'

如果它以字母开头,则接下来比较直到它不是字母

【讨论】:

  • 你确定你明白了OP的意思吗?自动从正则表达式字符串中解析出相关信息?
  • 在Java中,没有String.fromCharCode(97)
【解决方案2】:

我的方法主要是创建一个分析正则表达式的正则表达式,类似于

.*\(([a-z0-9\|]+)\).*

(免责声明:尚未检查其正则表达式语法是否正确)

这会在正则表达式中查找一个组,从左括号 \( 开始,然后包含任意数量的字母、数字和管道 [a-z0-9\|]+(假设文件扩展名正好允许这些字符),然后是结束括号\) 并将括号之间的内容返回为group(1)。组返回是 \(\) 对内的额外括号的用途。

在第一个例子中,这应该是avi|bmp,在第二个例子中应该是txt

然后,对group(1) 结果执行split("\|"),您将获得单独的扩展。

【讨论】:

    【解决方案3】:

    这可能是你需要的:

    public static List<String> getFileExtensionsFromRegex(String s) {
        Pattern pattern = Pattern.compile(("[a-zA-Z0-9]{2,}"));
        Matcher matcher = pattern.matcher(s);
        List<String> result = new ArrayList<>();
        while (matcher.find()) {
            result.add(matcher.group());
        }
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-29
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多