我在python脚本中有一个字符串,其中包含一些java
代码。
如何从中提取基类java类名,以便使用subprocess
执行它?
我认为它可以使用正则表达式实现,但我不知道如何。
样品:
a = """
import java.util.Scanner;
class sample{}
class second
{
static boolean check_prime(int a)
{
int c=0;
for (int i=1;i<=a; i++) {
if(a%i==0)
c++;
}
if(c == 2)
return true;
else
return false;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter two numbers");
int a = in.nextInt();
int b = in.nextInt();
if(check_prime(a) && check_prime(b))
{
if(b-a==2 || a-b==2)
System.out.println("They are twin primes");
else
System.out.println("They are not twin primes");
}
else
System.out.println("They might not be prime numbers");
}
}
"""
答案 0 :(得分:2)
主类是一个包含public static void main函数的类。
如果在您的环境中可行;您可以使用可以解析Java源代码的库,例如plyj
或javalang
:
#!/usr/bin/env python
import javalang # $ pip install javalang
tree = javalang.parse.parse(java_source)
name = next(klass.name for klass in tree.types
if isinstance(klass, javalang.tree.ClassDeclaration)
for m in klass.methods
if m.name == 'main' and m.modifiers.issuperset({'public', 'static'}))
# -> 'second'
如果在Java源代码顶部有一个包声明,例如package your_package;
,即如果完整的类名是your_package.second
,那么您可以将包名称设为tree.package.name
。
或者您可以使用解析器生成器(如grako
)并指定足以在您的案例中获取类名的Java语法子集。如果输入是高度规则的;如果你对代码结构的假设是错误的,你可以试试一个正则表达式并期望它失败。
答案 1 :(得分:1)
正如您猜测的那样,使用正则表达式可以对问题进行近似解决。但是,要记住一些技巧:
MyClass{
是合法且通用的MyClass<T>
等类名称之后提供,编译的.class
文件名称不受此类型参数的影响这些提示会导致搜索短语public class
的第一次出现,捕获下一轮字符,然后查找空格,{
或<
字符。
这是我提出的(可能有点难看):public\s*(?:abstract?)?\s*(?:static?)?\s*(?:final?)?\s*(?:strictfp?)?\s*class\s*(\w.*)\s*,?<.*$
答案 2 :(得分:1)
仅使用正则表达式几乎不会起作用。作为其不能的基本示例,请考虑以下事项:
public class A {
public static void ImDoingThisToMessYouUp () {
String s = "public static void main (String[] args) {}";
}
}
public class B {
public static void main (String[] args) {}
}
你明白了......正则表达式可能总是被愚弄相信他们找到的东西并不是你想要的东西。您必须依赖更高级的库进行解析。
我会选择J.F.Sebastian的回答。
答案 3 :(得分:0)
这是一种粗暴的方式:
import re
b = a.split()
str = b[b.index("class")+1]
javaclass = re.sub("{.*$","",str)
print (javaclass)
...基本上接受所有单词,并在第一次出现“class”后找到第一个单词。如果您遇到类似
的情况,它还会删除“{”及其后的任何内容class MyClass{
但是,如果文件中有多个类,则需要执行更多操作。
答案 4 :(得分:0)
正如我在评论中所说,使用re.findall()
这样:
re.findall('class (\w*)', a)
作为函数名称,findall()
可以找到所有类名。此处使用\w
将匹配所有ascii字母(如果您使用.*
,则优于class MyClass{
。)
关于查找主要课程,请使用re.S
,如下所示:
for i in re.split('\nclass ', a)[1:]: # will match the main code block and the class name of all classes
if re.search('\n\s*public static void main', i): # check if 'public static void main' in a class
print(re.search('(\w*)', i).group(1)) # and print out the class name
更简单的方法,只有一行使用列表理解:
[re.search('(\w*)', i).group(1) for i in re.split('\nclass ', a) if re.search('\n\s*public static void main', i)]