regex - 如何使用 Powershell 打印包含匹配字符串的整个函数?
问题描述
我需要在 .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;
/* */ }
/* */ }
- 我需要递归打印具有参数“HttpServletRequest”的整个函数
- 我需要递归打印具有字符串“getSession”的整个函数
即在这里,我只需要打印“doGet”和“service”函数。
我可以使用任何高级正则表达式来实现这一点吗?还有其他逻辑可以实现相同的目标吗?
实际上,我需要在 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
这是不正确的。
解决方案
- 我需要递归打印具有参数“HttpServletRequest”的整个函数
此正则表达式适用于您的示例(查看结果):
public.*?HttpServletRequest(?s).*?{.*?}
- 我需要递归打印具有字符串“getSession”的整个函数
此正则表达式适用于您的示例(查看结果):
public\s(?!class)(?s)[^}]+{[^}]+getSession[^}]+}
正如我所指出的,这些正则表达式适用于您的示例。如果您的代码变得更复杂,例如在函数中包含嵌套代码块,它们可能不再起作用。
如果您希望正则表达式为函数中的每个可能的代码片段做好准备,那么您将非常接近解析。你将不得不找到平衡的括号等等。在我看来,这对你的问题来说太过分了。您可能应该使用一个将所有函数分开的解析器,然后您可以使用正则表达式来仅识别所需的函数。
示例如何在 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 源代码,您可以执行以下解决方法:将文件分成几部分(当然是通过脚本)
- 如果您的文件可能包含多个类定义,则在每个类定义之前拆分
- 对于每个类片段,在每个方法定义之前拆分
之后,您将或多或少只有单一方法,不再需要确定它们的目的。然后您可以通过上面提供的正则表达式过滤它们。
仍然会有一个挑战:嵌套在方法中的方法呢?你需要关心他们吗?它会变得更加复杂......
推荐阅读
- axios - OpenAPI Generator typescript-axios multipart/form-data 如何使用生成函数
- kubernetes - 如何在代理 kubectl apply -f weave.net 后面安装这个 weave net add on
- python - 如何将每个数据帧行与元组的每个点进行比较并将最近点的索引分配给新列?
- android - 找不到 getApplicatinContent android studio
- server - 什么时候必须调用服务器来获取数据?
- javascript - ReactJS 从孙子调用父函数而不使用道具
- javascript - Angular Datatable:如何根据列数据禁用立即行复选框
- python - 当传统方式不起作用时如何更新点子?
- algorithm - 在 O(n) 时间内对包含 n 个字符的字符串数组进行排序
- makefile - 目标特定变量的潜在 Makefile 错误