Регулярное выражение, которое будет соответствовать объявлению метода Java

java regex methods

22781 просмотра

14 ответа

Мне нужно Regex, который будет соответствовать объявлению метода Java. Я придумал тот, который будет соответствовать объявлению метода, но он требует, чтобы открывающая скобка метода находилась в той же строке, что и объявление. Если у вас есть какие-либо предложения по улучшению моего регулярного выражения или просто есть лучшее, тогда, пожалуйста, отправьте ответ.

Вот мое регулярное выражение: "\w+ +\w+ *\(.*\) *\{"

Для тех, кто не знает, как выглядит Java-метод, я приведу базовый:

int foo()
{

}

Есть несколько необязательных частей к java-методам, которые также могут быть добавлены, но это единственные части, которые гарантированно имеют метод.

Обновление: мой текущий Regex предназначен "\w+ +\w+ *\([^\)]*\) *\{"для предотвращения ситуации, описанной Майком и adkom.

Автор: Anton Источник Размещён: 30.08.2019 03:37

Ответы (14)


2 плюса

Решение

Рассматривали ли вы соответствие фактическим возможным ключевым словам? такие как:

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

Вероятность совпадения может быть немного выше, хотя это также может затруднить чтение регулярных выражений ...

Автор: Mike Stone Размещён: 16.09.2008 01:50

23 плюса

(public|protected|private|static|\s) +[\w\<\>\[\]]+\s+(\w+) *\([^\)]*\) *(\{?|[^;])

Я думаю, что приведенное выше регулярное выражение может соответствовать практически всем возможным комбинациям объявлений методов Java, даже те, которые включают обобщенные значения и массивы, являются возвращаемыми аргументами, которым не соответствует регулярное выражение, предоставленное первоначальным автором.

Автор: Georgios Gousios Размещён: 11.05.2009 10:23

5 плюса

Посмотрев другие ответы, я пришел к следующему:

#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\[\] ,.&]+>[^>]*>[^>]*>)`

Ограничения:

  • ЛЮБОЙ параметр может иметь многоточие: "..." (Java допускает только последнее)
  • Максимум три уровня вложенных генериков: ( <...<...<...>...>...>хорошо, <...<...<...<...>...>...>...>плохо). Синтаксис внутри дженериков может быть очень фиктивным, и все равно может показаться нормальным этому регулярному выражению.
  • Не требует пробелов между типами и их (необязательными) открывающими шаблонами '<'
  • Распознает внутренние классы, но не мешает двум точкам рядом друг с другом, например, Class .... InnerClass

Ниже приведен необработанный код PhraseExpress (автотекст и описание в строке 1, тело в строке 2). Позвоните {#insert zJRgxJavaFuncSigThrSemicOrOpnCrly}, и вы получите это:

^[ \t]*(?:(?:public|protected|private)\s+)?(?:(static|final|native|synchronized|abstract|threadsafe|transient|(?:<[?\w\[\] ,&]+>)|(?:<[^<]*<[?\w\[\] ,&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,&]+>[^>]*>[^>]*>))\s+){0,}(?!return)\b([\w.]+)\b(?:|(?:<[?\w\[\] ,&]+>)|(?:<[^<]*<[?\w\[\] ,&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,&]+>[^>]*>[^>]*>))((?:\[\]){0,})\s+\b\w+\b\s*\(\s*(?:\b([\w.]+)\b(?:|(?:<[?\w\[\] ,&]+>)|(?:<[^<]*<[?\w\[\] ,&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,&]+>[^>]*>[^>]*>))((?:\[\]){0,})(\.\.\.)?\s+(\w+)\b(?![>\[])\s*(?:,\s+\b([\w.]+)\b(?:|(?:<[?\w\[\] ,&]+>)|(?:<[^<]*<[?\w\[\] ,&]+>[^>]*>)|(?:<[^<]*<[^<]*<[?\w\[\] ,&]+>[^>]*>[^>]*>))((?:\[\]){0,})(\.\.\.)?\s+(\w+)\b(?![>\[])\s*){0,})?\s*\)(?:\s*throws [\w.]+(\s*,\s*[\w.]+))?\s*(?:\{|;)[ \t]*$

Необработанный код:

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
Автор: aliteralmind Размещён: 26.09.2013 01:56

5 плюса

Я также нуждался в таком регулярном выражении и придумал это решение:

(?:(?:public|private|protected|static|final|native|synchronized|abstract|transient)+\s+)+[$_\w<>\[\]\s]*\s+[\$_\w]+\([^\)]*\)?\s*\{?[^\}]*\}?

Эта грамматика и ответ Георгиоса Гусиоса были полезны для построения регулярного выражения.

РЕДАКТИРОВАТЬ: С учетом обратной связи tharindu_DG, запрет на захват групп, улучшенное форматирование.

Автор: sbaltes Размещён: 20.04.2013 09:42

2 плюса

Я почти уверен, что движок регулярных выражений Java по умолчанию жадный, а это значит, что "\w+ +\w+ *\(.*\) *\{"он никогда не будет совпадать, так как .*в скобках все будет съедено после первого открытия. Я рекомендую вам заменить на .*[^)], таким образом вы выберете все закрывающие символы.

ПРИМЕЧАНИЕ: Майк Стоун исправил меня в комментариях, и так как большинство людей действительно не открывают комментарии (я знаю, что часто их не замечаю):

Жадность не означает, что она никогда не совпадет ... но она будет есть парены, если после нее будет больше паренов, чтобы удовлетворить остальное регулярное выражение ... так, например, "public void foo (int arg) {if (test) { System.exit (0);}} "не будет соответствовать должным образом ...

Автор: akdom Размещён: 16.09.2008 01:54

2 плюса

Я придумал это:

\b\w*\s*\w*\(.*?\)\s*\{[\x21-\x7E\s]*\}

Я протестировал его с помощью функции PHP, но он должен работать точно так же, это фрагмент кода, который я использовал:

function getProfilePic($url)
 {
    if(@open_image($url) !== FALSE)
     {
        @imagepng($image, 'images/profiles/' . $_SESSION['id'] . '.png');
        @imagedestroy($image);
        return TRUE;
     }
    else 
     {
        return FALSE;
     }
 }

БОЛЬШЕ ИНФОРМАЦИИ:

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
Автор: UnkwnTech Размещён: 16.09.2008 02:28

1 плюс

Совет:

Если вы собираетесь писать регулярное выражение в Perl, пожалуйста, используйте опции "xms", чтобы вы могли оставить пробелы и задокументировать регулярное выражение. Например, вы можете написать регулярное выражение, как:

 m{\w+ \s+      #return type
   \w+ \s*      #function name
   [(] [^)]* [)] #params
   \s* [{]           #open paren
  }xms

Один из вариантов (например, x) позволяет использовать # комментарии внутри регулярного выражения. Также используйте \ s вместо "". \ s обозначает любой «пустой» символ. Таким образом, вкладки также будут соответствовать - что вы хотели бы. В Perl вам не нужно использовать / /, вы можете использовать {} или <> или | |.

Не уверен, что другие языки имеют эту возможность. Если они это сделают, то, пожалуйста, используйте их.

Автор: SK Размещён: 16.09.2008 05:31

1 плюс

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

Приведенное выше регулярное выражение обнаружит все возможные определения метода Java. Проверено на множестве файлов с исходным кодом. Для включения конструкторов также используйте следующее регулярное выражение:

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

Автор: Souvik Das Размещён: 03.01.2018 06:19

1 плюс

Это выберет имя метода, а не всю строку.

(?<=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+
Автор: Abdullah Khan Размещён: 07.03.2019 07:01

0 плюса

Я создал регулярное выражение vim, чтобы сделать это для ctrlp / funky, основываясь на ответе Георгиоса Гусиоса.

    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

Я думаю, это выглядит так в Java:

^\s+(?:<\w+>\s+){0,3}(?:[\w\<\>\[\]])+\s+\w+\s*\([^\)]*\)(?:\w|\s|\{)+$
Автор: idbrii Размещён: 26.07.2012 03:02

0 плюса

Это для более конкретного случая использования, но гораздо проще, я думаю, его стоит поделиться. Я сделал это для нахождения методов public static void, т.е. действий контроллера Play, и сделал это из командной строки Windows / Cygwin, используя grep; см .: https://stackoverflow.com/a/7167115/34806

cat Foobar.java | grep -Pzo '(?s)public static void.*?\)\s+{'

Последние две записи из моего вывода следующие:

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) {
Автор: George Jempty Размещён: 16.01.2014 08:30

0 плюса

Я нашел ответ seba229 полезным, он отражает большинство сценариев, но не следующие,

public <T> T name(final Class<T> x, final T y)

Это регулярное выражение также уловит это.

((public|private|protected|static|final|native|synchronized|abstract|transient)+\s)+[\$_\w\<\>\w\s\[\]]*\s+[\$_\w]+\([^\)]*\)?\s*

Надеюсь это поможет.

Автор: tharindu_DG Размещён: 25.03.2016 09:23

0 плюса

(public|private|static|protected) ([A-Za-z0-9<>.]+) ([A-Za-z0-9]+)\(

Кроме того, вот последовательность замены, которую вы можете использовать в IntelliJ

$1 $2 $3(

Я использую это так:

$1 $2 aaa$3(

при преобразовании файлов Java в Kotlin для предотвращения автоматического превращения функций, начинающихся с «get», в переменные. Не работает с уровнем доступа «по умолчанию», но я сам этим не пользуюсь.

Автор: user1122069 Размещён: 27.08.2017 01:18

0 плюса

Начиная с git 2.19.0, встроенное регулярное выражение для Java теперь, кажется, работает хорошо, поэтому предоставление своего собственного может не потребоваться.

"!^[ \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]*\\([^;]*)$"

(Кажется, первая строка предназначена для фильтрации строк, которые похожи на объявления методов, но не являются.)

Автор: LarsH Размещён: 25.10.2018 07:09
Вопросы из категории :
32x32