匹配Java方法声明的正则表达式

匹配Java方法声明的正则表达式,java,regex,methods,Java,Regex,Methods,我需要一个与java方法声明匹配的正则表达式。我已经提出了一个匹配方法声明的方法,但是它要求方法的开始括号与声明在同一行。如果您有任何建议,以改善我的正则表达式或只是有一个更好的,然后请提交一个答案 这是我的正则表达式:“\w++\w++*\(.*\)*\{” 对于那些不知道java方法是什么样子的人,我将提供一个基本方法: int foo() { } java方法也可以添加几个可选部分,但这些是保证方法具有的唯一部分 更新: 我当前的正则表达式是“\w++\w++*\([^\)]*\)*{

我需要一个与java方法声明匹配的正则表达式。我已经提出了一个匹配方法声明的方法,但是它要求方法的开始括号与声明在同一行。如果您有任何建议,以改善我的正则表达式或只是有一个更好的,然后请提交一个答案

这是我的正则表达式:
“\w++\w++*\(.*\)*\{”

对于那些不知道java方法是什么样子的人,我将提供一个基本方法:

int foo()
{

}
java方法也可以添加几个可选部分,但这些是保证方法具有的唯一部分

更新:
我当前的正则表达式是
“\w++\w++*\([^\)]*\)*{”
,以防止出现Mike和adkom描述的情况。

您是否考虑过匹配实际可能的关键字?例如:

(?:(?:public)|(?:private)|(?:static)|(?:protected)\s+)*

它可能更容易正确匹配,但也可能使正则表达式更难阅读…

我很确定Java的正则表达式引擎默认情况下是贪婪的,这意味着
“\w++\w++*\(.\)*{”
将永远不会匹配,因为括号内的
*
将吃掉开头部分后的所有字符。我建议您将
*
替换为[^)],这样您将选择所有非结尾部分字符

注意:迈克·斯通在评论中纠正了我的错误,而且由于大多数人并没有真正打开评论(我知道我经常没有注意到他们):


贪婪并不意味着它永远不会匹配…但是如果后面有更多的paren来满足剩余的正则表达式,它会吃掉paren…因此,例如“public void foo(int arg){if(test){System.exit(0);}}”将无法正确匹配


我想到了这个:

\b\w*\s*\w*\(.*?\)\s*\{[\x21-\x7E\s]*\}
我用一个PHP函数测试了它,但它的工作原理应该是一样的,这是我使用的代码片段:

更多信息:

Options: case insensitive

Assert position at a word boundary «\b»
Match a single character that is a “word character” (letters, digits, etc.) «\w*»
   Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.) «\s*»
   Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match a single character that is a “word character” (letters, digits, etc.) «\w*»
   Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character “(” literally «\(»
Match any single character that is not a line break character «.*?»
   Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match the character “)” literally «\)»
Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.) «\s*»
   Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character “{” literally «\{»
Match a single character present in the list below «[\x21-\x7E\s]*»
   Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
   A character in the range between ASCII character 0x21 (33 decimal) and ASCII character 0x7E (126 decimal) «\x21-\x7E»
   A whitespace character (spaces, tabs, line breaks, etc.) «\s»
Match the character “}” literally «\}»


Created with RegexBuddy
提示:

如果您打算用Perl编写正则表达式,请使用“xms”选项,这样您就可以留下空格并记录正则表达式。例如,您可以编写一个正则表达式,如:

 m{\w+ \s+      #return type
   \w+ \s*      #function name
   [(] [^)]* [)] #params
   \s* [{]           #open paren
  }xms
其中一个选项(想想x)允许在正则表达式中使用#注释。也可以使用\s而不是“.”。s代表任何“空白”字符。因此制表符也会匹配——这是您想要的。在Perl中,您不需要使用//,您可以使用{}或<>或| |

不确定其他语言是否有此功能。如果有,请使用它们。

(公共受保护的私有静态)
(public|protected|private|static|\s) +[\w\<\>\[\]]+\s+(\w+) *\([^\)]*\) *(\{?|[^;])

我认为上面的regexp可以匹配几乎所有可能的Java方法声明组合,甚至包括泛型和数组在内的那些都是返回参数,而原始作者提供的regexp不匹配。

我基于Georgios Gousios的答案构建了一个vim regex来实现这一点

    let regex = '\v^\s+'                " preamble
    let regex .= '%(<\w+>\s+){0,3}'     " visibility, static, final
    let regex .= '%(\w|[<>[\]])+\s+'    " return type
    let regex .= '\w+\s*'               " method name
    let regex .= '\([^\)]*\)'           " method parameters
    let regex .= '%(\w|\s|\{)+$'        " postamble
let regex='\v^\s+'”前导
让正则表达式='%(\s+{0,3}''可见性,静态,最终
让regex.='%(\w |[\]])+\s+'”返回类型
让regex.='\w+\s*'“方法名
让regex.='\([^\)]*\')方法参数
让regex.='%(\w |\s | \{)+$”postamble
我猜在Java中是这样的:

^\s+(?:<\w+>\s+){0,3}(?:[\w\<\>\[\]])+\s+\w+\s*\([^\)]*\)(?:\w|\s|\{)+$
^\s+(?:\s+{0,3}(?:[\w\[\]])+\s+\w+\s*\([^\)]*\(?:\w\\s\{)+$

我也需要这样一个正则表达式,并提出了以下解决方案:

(?:(?:public|private|protected|static|final|native|synchronized|abstract|transient)+\s+)+[$_\w<>\[\]\s]*\s+[\$_\w]+\([^\)]*\)?\s*\{?[^\}]*\}?
(?:(?:public | private | protected | static | final | native | synchronized | abstract | transient)+\s+[$\uw\[\]\s]*\s+[\$\uw]+\[^\]*\)?\s*{?
这和Georgios Gousios的答案对于构建正则表达式非常有用


编辑:考虑了tharindu_DG的反馈,使小组不捕获,改进了格式。

在查看了其他答案后,我得出以下结论:

#permission
   ^[ \t]*(?:(?:public|protected|private)\s+)?
#keywords
   (?:(static|final|native|synchronized|abstract|threadsafe|transient|{#insert zJRgx123GenericsNotInGroup})\s+){0,}
#return type
   #If return type is "return" then it's actually a 'return funcName();' line. Ignore.
   (?!return)
   \b([\w.]+)\b(?:|{#insert zJRgx123GenericsNotInGroup})((?:\[\]){0,})\s+
#function name
   \b\w+\b\s*
#parameters
   \(
      #one
         \s*(?:\b([\w.]+)\b(?:|{#insert zJRgx123GenericsNotInGroup})((?:\[\]){0,})(\.\.\.)?\s+(\w+)\b(?![>\[])
      #two and up
         \(\s*(?:,\s+\b([\w.]+)\b(?:|{#insert zJRgx123GenericsNotInGroup})((?:\[\]){0,})(\.\.\.)?\s+(\w+)\b(?![>\[])\s*){0,})?\s*
   \)
#post parameters
   (?:\s*throws [\w.]+(\s*,\s*[\w.]+))?
#close-curly (concrete) or semi-colon (abstract)
   \s*(?:\{|;)[ \t]*$

其中
{#insert zJRgx123GenericsNotInGroup}
等于

`(?:<[?\w\[\] ,.&]+>)|(?:<[^<]*<[?\w\[\] ,.&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,.&]+>[^>]*>[^>]*>)`

原始代码:

zJRgx123GenericsNotInGroup -- To precede return-type    (?:<[?\w\[\] ,.&]+>)|(?:<[^<]*<[?\w\[\] ,.&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,.&]+>[^>]*>[^>]*>)  zJRgx123GenericsNotInGroup
zJRgx0OrMoreParams  \s*(?:{#insert zJRgxParamTypeName}\s*(?:,\s+{#insert zJRgxParamTypeName}\s*){0,})?\s*   zJRgx0OrMoreParams
zJRgxJavaFuncNmThrClsPrn_M_fnm -- Needs zvFOBJ_NAME (?<=\s)\b{#insert zvFOBJ_NAME}{#insert zzJRgxPostFuncNmThrClsPrn}   zJRgxJavaFuncNmThrClsPrn_M_fnm
zJRgxJavaFuncSigThrSemicOrOpnCrly -(**)-    {#insert zzJRgxJavaFuncSigPreFuncName}\w+{#insert zzJRgxJavaFuncSigPostFuncName}    zJRgxJavaFuncSigThrSemicOrOpnCrly
zJRgxJavaFuncSigThrSemicOrOpnCrly_M_fnm -- Needs zvFOBJ_NAME    {#insert zzJRgxJavaFuncSigPreFuncName}{#insert zvFOBJ_NAME}{#insert zzJRgxJavaFuncSigPostFuncName}  zJRgxJavaFuncSigThrSemicOrOpnCrly_M_fnm
zJRgxOptKeywordsBtwScopeAndRetType  (?:(static|final|native|synchronized|abstract|threadsafe|transient|{#insert zJRgx123GenericsNotInGroup})\s+){0,}    zJRgxOptKeywordsBtwScopeAndRetType
zJRgxOptionalPubProtPriv    (?:(?:public|protected|private)\s+)?    zJRgxOptionalPubProtPriv
zJRgxParamTypeName -(**)- Ends w/ '\b(?![>\[])' to NOT find <? 'extends XClass'> or ...[]>  (*Original: zJRgxParamTypeName, Needed by: zJRgxParamTypeName[4FQPTV,ForDel[NmsOnly,Types]]*){#insert zJRgxTypeW0123GenericsArry}(\.\.\.)?\s+(\w+)\b(?![>\[])   zJRgxParamTypeName
zJRgxTypeW0123GenericsArry -- Grp1=Type, Grp2='[]', if any  \b([\w.]+)\b(?:|{#insert zJRgx123GenericsNotInGroup})((?:\[\]){0,}) zJRgxTypeW0123GenericsArry
zvTTL_PRMS_stL1c    {#insert zCutL1c}{#SETPHRASE -description zvTTL_PRMS -content {#INSERTCLIPBOARD} -autotext zvTTL_PRMS -folder ctvv_folder}  zvTTL_PRMS_stL1c
zvTTL_PRMS_stL1cSvRstrCB    {#insert zvCB_CONTENTS_stCB}{#insert zvTTL_PRMS_stL1c}{#insert zSetCBToCB_CONTENTS} zvTTL_PRMS_stL1cSvRstrCB
zvTTL_PRMS_stPrompt {#SETPHRASE -description zvTTL_PRMS -content {#INPUT -head How many parameters? -single} -autotext zvTTL_PRMS -folder ctvv_folder}  zvTTL_PRMS_stPrompt
zzJRgxJavaFuncNmThrClsPrn_M_fnmTtlp -- Needs zvFOBJ_NAME, zvTTL_PRMS    (?<=[ \t])\b{#insert zvFOBJ_NAME}\b\s*\(\s*{#insert {#COND -if {#insert zvTTL_PRMS} = 0 -then z1slp -else zzParamsGT0_M_ttlp}}\)    zzJRgxJavaFuncNmThrClsPrn_M_fnmTtlp
zzJRgxJavaFuncSigPostFuncName   {#insert zzJRgxPostFuncNmThrClsPrn}(?:\s*throws \b(?:[\w.]+)\b(\s*,\s*\b(?:[\w.]+)\b))?\s*(?:\{|;)[ \t]*$   zzJRgxJavaFuncSigPostFuncName
zzJRgxJavaFuncSigPreFuncName    (*If a type has generics, there may be no spaces between it and the first open '<', also requires generics with three nestings at the most (<...<...<...>...>...> okay, <...<...<...<...>...>...>...> not)*)^[ \t]*{#insert zJRgxOptionalPubProtPriv}{#insert zJRgxOptKeywordsBtwScopeAndRetType}(*To prevent 'return funcName();' from being recognized:*)(?!return){#insert zJRgxTypeW0123GenericsArry}\s+\b  zzJRgxJavaFuncSigPreFuncName
zzJRgxPostFuncNmThrClsPrn   \b\s*\({#insert zJRgx0OrMoreParams}\)   zzJRgxPostFuncNmThrClsPrn
zzParamsGT0_M_ttlp -- Needs zvTTL_PRMS  {#insert zJRgxParamTypeName}\s*{#insert {#COND -if {#insert zvTTL_PRMS} = 1 -then z1slp -else zzParamsGT1_M_ttlp}}  zzParamsGT0_M_ttlp
zzParamsGT1_M_ttlp  {#LOOP ,\s+{#insert zJRgxParamTypeName}\s* -count {#CALC {#insert zvTTL_PRMS} - 1 -round 0 -thousands none}}    zzParamsGT1_M_ttlp
zJRgx123GenericsNotInGroup——在返回类型(?:)|(?:)|(?:)zJRgx123GenericsNotInGroup之前
zJRgx0OrMoreParams\s*(?:{插入zJRgxParamTypeName}\s*(?:,\s+{插入zJRgxParamTypeName}\s*){0,})?\s*zJRgx0OrMoreParams

zjrgxjavafuncnmthrclspn_M_fnm——需要zvFOBJ_名称(?这是为了一个更具体的用例,但它简单得多,我相信它值得分享。我这样做是为了找到“public static void”方法,即播放控制器动作,我使用grep从Windows/Cygwin命令行执行此操作;请参阅:

我的输出的最后两项如下:

public static void activeWorkEventStations (String type,
            String symbol,
            String section,
            String day,
            String priority,
            @As("yyyy-MM-dd") Date scheduleDepartureDate) {
public static void getActiveScheduleChangeLogs(String type,
            String symbol,
            String section,
            String day,
            String priority,
            @As("yyyy-MM-dd") Date scheduleDepartureDate) {

我发现seba229的答案很有用,它捕获了大多数场景,但没有以下内容

public <T> T name(final Class<T> x, final T y)
public T name(最终类x,最终类y)
这个正则表达式也将捕获这一点

((public|private|protected|static|final|native|synchronized|abstract|transient)+\s)+[\$_\w\<\>\w\s\[\]]*\s+[\$_\w]+\([^\)]*\)?\s*
((公共|私有|受保护|静态|最终|本机|同步|抽象|瞬态)+\s)+[\$\uw\\w\s\[\]*\s+[\$\uw]+\([^\)]*\?\s*
希望这有帮助

(public|private|static|protected) ([A-Za-z0-9<>.]+) ([A-Za-z0-9]+)\(
我是这样使用它的:

$1 $2 aaa$3(
在将Java文件转换为Kotlin以防止以“get”开头的函数自动转换为变量时,使用“default”访问级别不起作用,但我自己不会使用太多。

(public | private | static | protected | abstract | native | synchronized)+([a-zA-Z0-Z0-9.\u?,]+)+([a-zA-Z0-Z0-9\\\+)*([a-zA-Z0-Z0-9\\\\\\\\\\\,\n]*)*([a-zA-Z0-9\\ n]*)*\{

上面的正则表达式将检测所有可能的java方法定义。在大量源代码文件上进行测试。要包含构造函数,请使用下面的正则表达式:

(公共的、私有的、静态的、受保护的、抽象的、本地的、同步的)+([a-zA-Z0-9.\u?,]*)+([a-zA-Z0-9.\u]+)*\([a-zA-Z0-9\\[\\].\u?,\ n]*\\\([a-zA-Z0-9.\uN]*)*\\{{/code>从git 2.19.0开始,现在看来你自己的系统运行得很好,可能没有必要了

"!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
"^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$"

(第一行似乎用于筛选出与方法声明相似但不相似的行。)

这将选择方法的名称,而不是整行

(?<=public static void )\w+|(?<=private static void )\w+|(?<=protected static void )\w+|(?<=public void )\w+|(?<=private void )\w+|(?<=protected void )\w+|(?<=public final void)\w+|(?<=private final void)\w+|(?<=protected final void)\w+|(?<=private void )\w+|(?<=protected void )\w+|(?<=public static final void )\w+|(?<=private static final void )\w+|(?<=public final static void )\w+|(?<=protected final static void )\\w+|(?<=private final static void )\w+|(?<=protected final static void )\w+|(?<=void )\w+|(?<=private static )\w+

(?我不知道Java方法声明是什么样子
$1 $2 $3(
$1 $2 aaa$3(
"!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
"^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$"
(?<=public static void )\w+|(?<=private static void )\w+|(?<=protected static void )\w+|(?<=public void )\w+|(?<=private void )\w+|(?<=protected void )\w+|(?<=public final void)\w+|(?<=private final void)\w+|(?<=protected final void)\w+|(?<=private void )\w+|(?<=protected void )\w+|(?<=public static final void )\w+|(?<=private static final void )\w+|(?<=public final static void )\w+|(?<=protected final static void )\\w+|(?<=private final static void )\w+|(?<=protected final static void )\w+|(?<=void )\w+|(?<=private static )\w+