Как напечатать всю функцию, содержащую совпадающую строку, используя Powershell? - PullRequest
0 голосов
/ 18 апреля 2020

Мне нужно найти определенную строку в файле. java и выбрать только функцию, содержащую строку.

Пример кода:

/*    */ package com.mypackage.servlets;

/*    */ import javax.servlet.http.HttpServletRequest;
/*    */ import javax.servlet.http.HttpServletResponse;


/*    */ public class GetChallengeServlet
/*    */   extends HttpServlet
/*    */ {

            public  int hello(){

            }

/*    */   public void doGet(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse) throws ServletException, IOException {}
/*    */   
/* 22 */   String userName = null;
/*    */ 
            public  int hello2(){

            }
/*    */   
/*    */   public void service(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse) throws ServletException, IOException {
/* 26 */     this.userName = null;
/* 27 */     String str1 = null;
/* 28 */     String str2 = null;
/* 29 */     HttpSession httpSession = paramHttpServletRequest.getSession(false);
/* 30 */     PrintWriter printWriter = null;

/*    */   }
/*    */ }
  1. Мне нужно рекурсивно вывести всю функцию с параметром "HttpServletRequest"
  2. Мне нужно рекурсивно вывести всю функцию, содержащую строку "getSession"

т.е. здесь мне нужно вывести "doGet" и только «сервисные» функции.

Могу ли я достичь этого с помощью любого продвинутого регулярного выражения? Любой другой лог c для достижения того же?

На самом деле мне нужно кодировать в Powershell, Bash и Python. Я надеюсь, что решение будет работать для всех языков.

Я пробовал ниже Powershell

$input = gc -Raw 'GetChallengeServlet.java'
$sections = $input | select-string -AllMatches '(?smi)(public.*\(HttpServlet.*?(public|private|protected))'
$sections.Matches | foreach {$_.Value}

Но он выбирает:

public class GetChallengeServlet
/*    */   extends HttpServlet
/*    */ {

            public  int hello(){

            }

/*    */   public void doGet(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse) throws ServletException, IOException {}
/*    */   
/* 22 */   String userName = null;
/*    */ 
            public

Это не правильно.

1 Ответ

0 голосов
/ 19 апреля 2020
  1. Мне нужно рекурсивно распечатать всю функцию, которая имеет параметр "HttpServletRequest"

Это регулярное выражение будет работать для вашего примера ( просмотреть результат ):

public.*?HttpServletRequest(?s).*?{.*?}
Мне нужно рекурсивно вывести всю функцию со строкой "getSession"

Это регулярное выражение будет работать для вашего примера ( просмотреть результат ):

public\s(?!class)(?s)[^}]+{[^}]+getSession[^}]+}

Как я уже говорил, эти регулярные выражения будут работать для вашего примера. Они, вероятно, больше не будут работать, если ваш код становится более сложным, например, содержит вложенные блоки кода внутри ваших функций.

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


Пример использования регулярных выражений в PowerShell:

$content = Get-Content .\GetChallengeServlet.java -Raw
Select-String -InputObject $content -Pattern 'public.*?HttpServletRequest(?s).*?{.*?}' -AllMatches | ForEach-Object {$_.Matches.Value}

Вывод:

public void doGet(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse) t
hrows ServletException, IOException {}
public void service(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse)
 throws ServletException, IOException {
/* 26 */     this.userName = null;
/* 27 */     String str1 = null;
/* 28 */     String str2 = null;
/* 29 */     HttpSession httpSession = paramHttpServletRequest.getSession(false);
/* 30 */     PrintWriter printWriter = null;

/*    */   }

Подсказка, чтобы перейти к более сложным примерам, вместо того, чтобы действительно анализировать исходный код java, вы можете сделать обходной путь, подобный этому: Разделите ваши файлы на части (по сценарию, конечно)

  1. Разделить перед каждым определением класса, если ваши файлы могут содержать несколько определений класса
  2. Для каждого элемента класса, разделить перед каждым определением метода

После этого у вас будут более или менее единственные методы, и вам больше не придется определять их цели. Затем вы можете отфильтровать их по приведенным выше регулярным выражениям.

По-прежнему будет проблема: как насчет методов, которые вложены в методы? Будете ли вы заботиться о них? Это будет еще сложнее ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...