用于标识符(字母、数字和下划线)的Java正则表达式

用于标识符(字母、数字和下划线)的Java正则表达式,java,regex,string,Java,Regex,String,假设您提供了一个类似以下内容的输入(identifier1 identifier_2 23 4) 我想在每个标识符后面添加一个#符号,它可以包含字母、数字和下划线。它们只能以字母开头,后跟字母、数字和下划线的变体。我的方法是这样的: input.replaceAll("[A-Za-z0-9_]+", "$0#"); 但是,这也会将#符号放在我想要排除的每个数字后面。结果应该是(标识符1#标识符2#23 4)。有可能用正则表达式解决这个问题吗?您当前的正则表达式说 一个或多个大写或小写字母、数字

假设您提供了一个类似以下内容的输入
(identifier1 identifier_2 23 4)

我想在每个标识符后面添加一个
#
符号,它可以包含字母、数字和下划线。它们只能以字母开头,后跟字母、数字和下划线的变体。我的方法是这样的:

input.replaceAll("[A-Za-z0-9_]+", "$0#");

但是,这也会将
#
符号放在我想要排除的每个数字后面。结果应该是
(标识符1#标识符2#23 4)
。有可能用正则表达式解决这个问题吗?

您当前的正则表达式说

一个或多个大写或小写字母、数字或下划线 随便什么命令

根据该正则表达式,
54
是一个有效标识符

你真的想写

一个字母,后跟任意数量的字母、数字或数字 以任何顺序强调

这将用代码编写为:

input.replaceAll("[A-Za-z][A-Za-z0-9_]*", "$0#");

Wiktor注意到,这个正则表达式仍然会匹配非标识符内部的“标识符”。要解决此问题,可以使用以下变体:

input.replaceAll("\\b([A-Za-z][A-Za-z0-9_]*)\\b", "$1#")
这将拒绝将
123ab123
作为有效标识符,但在
123 ab123
更新2中接受
ab123
报告说:

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

    简而言之,标识符是从字母、数字、下划线或美元符号中选择的一个或多个字符。唯一的限制是第一个字符不能是数字
所以,你最好使用

String pattern = "(?:\\b[_a-zA-Z]|\\B\\$)[_$a-zA-Z0-9]*+";

更新 根据,标识符regex是
[\u a-zA-Z][\u a-zA-Z0-9]*

因此,您可以使用

String pattern = "\\b[_a-zA-Z][_a-zA-Z0-9]*\\b";
注意它允许
\uuuuuuuuuuuuuuuuuuuuuuuuuu

你可以用

String p = "\\b_*[a-zA-Z][_a-zA-Z0-9]*\\b";
为了避免这种情况。看

输出:
(标识符1#标识符2#23 4)uuuuu33

旧答案 您可以使用以下模式:

String p = "\\b(?!\\d+\\b)[A-Za-z0-9]+(?:_[A-Za-z0-9]+)*\\b";
或者(如果末尾可能出现一个
\uu
):

该模式要求整个单词(因为表达式包含单词边界
\b
)不应等于一个数字(使用
(?!\d+\b)
检查),且展开部分
[a-Za-z0-9]+(?:[a-Za-z0-9])*
匹配后跟零个或多个下划线序列的非下划线单词字符块,后跟非下划线单词字符块

:


输出:
(标识符1#标识符2#23 4)uuuuu33

不是吗?你的意思是,在
23
4
之后不应该出现
?我只想在标识符后面放
符号,而不是在数字后面。所以它应该是(标识符1#标识符2#23 4)我认为
\b(?!\d++\b)[A-Za-z0-9+\b
会有所帮助。但它不会排除像
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
这样的字符串。要排除硫硒,您可以使用
\b(?!\u+\ b |\d++\b)[A-Za-z0-9_+\b
进一步限制。或者甚至。我假设括号不是输入的一部分-如果是,则需要附加规则。对于所需内容,该表达式似乎相当复杂<代码>(?i)[a-z_uuw]\*应该足够了(或其他答案/评论中发布的同等内容)。不知道具体需要什么。我建议其他选择。输入是否应以
结尾?我也提出了一个解决方案。但是,如果两个正则表达式是等价的,那么应该选择最短的或最容易理解的。它们不是等价的。不,它们不是等价的,但可能达到相同的目的。如果开始时对
[a-zA-Z]
的要求已经排除了该选项,那么为什么要检查它是否是一个数字呢?这将与
a\uuuuuuuuuuuuu
匹配。允许吗?此外,此正则表达式将在
%%%A_B^^^
内部匹配
A_B
。或者它会在
34z456,,,
中找到
z456
,根据OP的帖子,是:“以字母开头,后跟字母、数字和下划线的变体”不,正如你所见,如果字符串以数字开头,它甚至会找到匹配项。任何东西。Wiktor就在这里,需要单词边界或其他分隔符来删除这些大小写。它将匹配
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
字符串。它是有效的标识符吗?
String p = "\\b(?!\\d+\\b)[A-Za-z0-9]+(?:_[A-Za-z0-9]+)*\\b";
String p = "\\b(?!\\d+\\b)[A-Za-z0-9]+(?:_[A-Za-z0-9]*)*\\b";
String s = "(identifier1 identifier_2 23 4) ____ 33"; 
String p = "\\b(?!\\d+\\b)[A-Za-z0-9]+(?:_[A-Za-z0-9]*)*\\b";
System.out.println(s.replaceAll(p, "$0#"));