簡體   English   中英

長命名捕獲組正則表達式模式的問題

[英]Problem with long named capturing groups regex patterns

我已經創建並初步驗證了以下正則表達式。 它旨在成為標記器的一部分,在將某些模式傳遞給解析器之前對其進行識別和分組。

(?<FUNCTION> (?!CUP\(\d+\)|CDN\(\d+\))[A-Z]+\(\d*\)|[A-Z]+\(\d+,\d+\))
| (?<NUMBER>\d+|\d*\.\d+)
| (?<RELATION>==|<=|>=|!=|<|>|CUP\(\d+\)|CDN\(\d+\))
| (?<EOL>;)
| (?<OPENPAR>\()
| (?<CLOSEPAR>\))
| (?<OPERATION>\*|\+|-|\/])
| (?<SPACE>\s+)
| (?<ERROR>.)

有了上述內容,使用正則表達式引擎屬性以及降低子模式的復雜性,我能夠正確捕獲所有組。 下面的示例文本按預期匹配,在命名捕獲組中捕獲正確的部分(在 regex101: https://regex101.com/r/nvRyjt/2 上)。 到目前為止,一切都很好。

TICK()<=.(2*STDEVEMA(14))+EMA(14);
TREND(14,2)==UP(2);
TICK()>EMA(14);
TREND(14)==UP(1);
EMA(14)CUP(2)EMA(28);
EMA(14)CDN(2)EMA(28)
2*3==6;
ssst2222  \\\\///???
sfgjsf

當我嘗試在 java.util.regex 中使用此表達式時,問題就開始了。 模式僅捕獲較小組的少數出現,並且條目文本的剩余可識別部分被跳過或顯示為“空值”。 我嘗試了許多組合,包括將模式限制為兩個或三個組,但對於導致意外行為的原因沒有明確的結論。 搜索到目前為止發布的問題,我清楚地注意到 regex101(和一般的 PCRE)不是驗證稍后在 java 中使用的正則表達式的好工具:-)。 在發布此內容時,我想問以下問題:

  1. 你們中是否有人知道關於 Pattern 和 Matcher 類如何工作(尤其是正則表達式引擎)的任何深入描述?
  2. 您是否在復雜的正則表達式模式中遇到過類似的問題(也許 java.util 的限制不那么明顯)?

負前瞻的更具體的事情。 像這樣的構造:

(?<FUNCTION> (?!CUP\(\d+\)|CDN\(\d+\))[A-Z]+\(\d*\)|[A-Z]+\(\d+,\d+\))

僅跳過第一個字符“C”,將預期將被跳過的關鍵字的剩余部分(CUP 或 CDN)視為有效(在本例中為 UP 或 DN)。 對此有什么想法嗎? 先感謝您 !

我不確定我是否可以回答您的問題,但您可以嘗試以下方法。

使用 regex101 站點上的代碼生成器工具(在左側工具下)並使用 java 作為您的語言。

從生成的正則表達式字符串中刪除\n 不刪除它可能會導致您的問題?!

package com.company;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    public static void main(String[] args) {

        final String regex = "(?<FUNCTION> (?!CUP\\(\\d+\\)|CDN\\(\\d+\\))[A-Z]+\\(\\d*\\)|[A-Z]+\\(\\d+,\\d+\\))" +
                " | (?<NUMBER>\\d+|\\d*\\.\\d+)" +
                " | (?<RELATION>==|<=|>=|!=|<|>|CUP\\(\\d+\\)|CDN\\(\\d+\\))" +
                " | (?<EOL>;)" +
                " | (?<OPENPAR>\\()" +
                " | (?<CLOSEPAR>\\))" +
                " | (?<OPERATION>\\*|\\+|-|\\/])" +
                " | (?<SPACE>\\s+)" +
                " | (?<ERROR>.)";
        final String string = "TICK()<=.(2*STDEVEMA(14))+EMA(14);\n"
                + "TREND(14,2)==UP(2);\n"
                + "TICK()>EMA(14);\n"
                + "TREND(14)==UP(1);\n"
                + "EMA(14)CUP(2)EMA(28);\n"
                + "EMA(14)CDN(2)EMA(28)\n"
                + "2*3==6;\n"
                + "ssst2222  \\\\\\\\///???\n"
                + "sfgjsf\n";

        final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE | Pattern.COMMENTS);
        final Matcher matcher = pattern.matcher(string);

        while (matcher.find()) {
            System.out.println("Full match: " + matcher.group(0));
            for (int i = 1; i <= matcher.groupCount(); i++) {
                System.out.println("Group " + i + ": " + matcher.group(i));
            }
        }
    }
}

謹防

我得到了 67 個匹配項,regex101 得到了 89 個匹配項。

這是因為 SPACE 在 regex101 中的 ERROR 之前匹配。 在 Java 中不是。 可能是 regex101 支持的擴展模式,在 Java 中似乎不可用。

例子:

final String string = "TICK()<=."

給出 Java:

Full match: TICK()
Full match: <=
Full match: .

給出正則表達式101:

Match 1  Full match 0-6 TICK()
Match 2  Full match 6-8 <= 
Match 3  Full match 8-8  
Match 4  Full match 8-9 .

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM