Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为Java标识符优化正则表达式。将结尾和其他部分中的数字分开_Java_Regex_Groovy - Fatal编程技术网

为Java标识符优化正则表达式。将结尾和其他部分中的数字分开

为Java标识符优化正则表达式。将结尾和其他部分中的数字分开,java,regex,groovy,Java,Regex,Groovy,我需要读取一个字符串作为有效的Java标识符,并分别获取结尾(如果有)和开始部分的数字 a1 -> a,1 a -> a, a123b -> a123b, ab123 -> ab, 123 a123b456 -> a123b, 456 a123b456c789 -> a123b456c, 789 _a123b456c789 -> _a123b456c, 789 我已经编写了一对正则表达式,并对其进行了测试,它们看起来可以正常工作 ([a-zA-Z_]

我需要读取一个字符串作为有效的Java标识符,并分别获取结尾(如果有)和开始部分的数字

a1 -> a,1
a  -> a,
a123b -> a123b,
ab123 -> ab, 123
a123b456 -> a123b, 456
a123b456c789 -> a123b456c, 789
_a123b456c789 -> _a123b456c, 789
我已经编写了一对正则表达式,并对其进行了测试,它们看起来可以正常工作

([a-zA-Z_][a-zA-Z0-9_]*[a-zA-Z_]|[a-zA-Z_])(\d+)$
([a-zA-Z_](?:[a-zA-Z0-9_]*[a-zA-Z_])?)(\d+)$
我怎样才能缩短它们?或者你能建议另一个正则表达式吗

我无法为\w更改[a-zA-Z_],因为最后一个数字也是

(我们讨论的是Java/Groovy中\\for\\replacement之前的正则表达式字符串)

  • 每个标识符必须至少有一个字符。
  • 第一个字符必须从字母、下划线或美元符号中选取。第一个字符不能是数字。
  • 其余字符(除第一个字符外)可以来自:字母、数字、下划线或美元符号。换句话说,它可以是任何有效的标识符字符。

    简而言之,标识符是从字母、数字、下划线或美元符号中选择的一个或多个字符。唯一的限制是第一个字符不能是数字
并加入:

但是,惯例是始终以字母开头变量名,而不是“$”或“\u1”。此外,根据惯例,美元符号字符从未使用过

您可以使用此选项来匹配任何有效变量,并将起始字符块放入一个组,将所有尾随数字放入另一个组:

^(?!\d)([$\w]+?)(\d*)$

或仅与遵循约定的标识符匹配的:

^(?![\d_])(\w+?)(\d*)$

详细信息

  • ^
    -字符串的开头
  • (?!\d)
    -第一个字符不能是数字(
    (?![\d])
    如果第一个字符是数字或
    ,则匹配将失败)
  • ([$\w]+?)
    -第1组:一个或多个单词或
    $
    字符(
    (\w+?)
    将只匹配字母/数字/
    字符),尽可能少(因为
    +?
    是惰性量词),直到第一次出现
  • (\d*)$
    -第2组:字符串末尾的零位或多位(
    $
:


编辑:我试图使我的解决方案尽可能简单,但我没有考虑足够长的时间,所以它是不正确的。看看公认的答案


我相信您可以将其缩短为
^([a-zA-Z_u2;][a-zA-Z_2;d]*[^\d])(\d*)$
-将所有可能的字符与结尾处的数字进行匹配,而不是一个数字

请注意,在Java/Groovy正则表达式中,
\w
默认情况下与
[a-zA-Z0-9\]
匹配。仅当您传递了
Pattern.UNICODE\u CHARACTER\u CLASS
时,
\w
模式将匹配所有UNICODE字母和数字。字符串必须是变量名。所以,我不是在搜索所有的Unicode字母和数字。这里没关系。考虑到您的第一篇评论,我得出结论,我们可以影响\\w等缩短模式的工作方式?可以更改速记字符类Unicode行为。而且,您的逻辑是正确的。但是,如果您的意思是一个有效的Java标识符,那么您的正则表达式也应该能够匹配Java标识符中出现的
$
。谢谢。我懂了。。。是的,我可以将[a-zA-Z0-9_u2;]更改为\\w,并且我应该在开始处添加^at以检查字符串的开头。但是最后一个“?”有什么用呢?将(\\d+)更改为(\\d*)将完成相同的工作,不是吗?并且不可能使用不同的逻辑吗?你的答案对我来说肯定非常有用,检查字符串的开头,但我有点失望——逻辑上它和我发现的是一样的。我在正则表达式方面是个新手。你所看到的怪物怎么可能是几乎相同的解决方案?@Gangnus不知道你所说的“怪物”是什么意思。你在这个问题上没有提出任何要求,除了帮助你修复代码(通过从你尝试过的模式中推断出要求),我想我自己也无能为力。我的意思是,你在这方面的经验是我的好几倍。没有冒犯的意思,相反。。。至于需求,在问题的开头,它们写在我的正则表达式之前。@Gangnus:这些不是需求,只是一些测试用例。您应该显式地编写有效的Java标识符。
^([a-zA-Z\d]*[^\d])(\d*)$
不正确,因为变量名不能以数字开头。是的,我刚刚意识到这一点。编辑以使其正确。(希望)不,
[^\d]
表示除数字以外的任何字符。任何。我在你第二次评论之前编辑过。现在我不知道它是否比问题中的还要短,这不是写得短的问题<代码>[^\d]
匹配
*
Ł
Щ
。。。
// Non-convention Java identifier
def res = 'a123b$456_c789' =~ /^(?!\d)([$\w]+?)(\d*)$/
print("${res[0][1]} : ${res[0][2]}") // => a123b$456_c : 789

// Convention Java identifier
def res2 = 'a123b456_c' =~ /^(?!\d)([$\w]+?)(\d*)$/
print("${res2[0][1]} : ${res2[0][2]}")  // => a123b456_c :