Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中提取java主类名_Python_Regex_Subprocess - Fatal编程技术网

在python中提取java主类名

在python中提取java主类名,python,regex,subprocess,Python,Regex,Subprocess,我有一个python脚本中的字符串,其中包含一些java代码 如何从中提取基本java类名,以便使用子流程执行它? 我认为使用正则表达式可以实现,但我不知道如何实现。 样本: 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++) {

我有一个python脚本中的字符串,其中包含一些
java
代码
如何从中提取基本java类名,以便使用
子流程执行它?
我认为使用正则表达式可以实现,但我不知道如何实现。

样本:

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");
    }
}
"""
a=”“”
导入java.util.Scanner;
类样本{}
二等
{
静态布尔校验素数(int a)
{
int c=0;
对于(inti=1;i,这里有一个粗略的方法:

import re

b = a.split()
str = b[b.index("class")+1]
javaclass = re.sub("{.*$","",str)
print (javaclass)
…它基本上取所有的单词,并在第一次出现“class”之后找到第一个单词。如果你遇到这样的情况,它还会删除“{”及其后面的任何内容

class MyClass{
但是,如果一个文件中有多个类,则需要做更多的工作

主类是包含公共静态void主函数的类

如果在您的环境中可能,您可以使用可以解析Java源代码的库,例如或:

如果Java源代码顶部有一个包声明,例如,
package your_package;
,也就是说,如果完整的类名是
your_package.second
,那么您可以将包名设置为
tree.package.name

或者,您可以使用解析器生成器,例如,并指定一个Java语法子集,该子集足以在您的案例中获取类名。如果输入是高度规则的,您可以尝试一个正则表达式,如果您对代码结构的假设是错误的,则它可能会失败。

如我在注释中所述,使用如下:

re.findall('class (\w*)', a)
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
作为函数名,
findall()


关于查找主类,如下所示:

re.findall('class (\w*)', a)
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)]

正如您所猜测的,使用正则表达式可以近似解决该问题。但是,有一些技巧需要记住:

  • 类名不能以空格结尾,因为
    MyClass{
    是合法和常见的
  • 可以在类名称之后提供类型参数,例如
    MyClass
    ,并且编译的
    。class
    文件的名称将不受此类型参数的影响
  • 一个文件可以有多个顶级类,但是不能将一个顶级类声明为公共类,并且此类不能与文件同名
  • 与文件同名的公共类可能具有内部类(甚至可能是公共的),但这些类必须位于外部类声明之后

  • 这些提示导致搜索短语“代码>公共类< /代码>,捕获下一个字符,然后查找空白,一个<代码> {<代码>或<代码> 只使用正则表达式几乎不起作用。

    public class A {
         public static void ImDoingThisToMessYouUp () {
              String s = "public static void main (String[] args) {}";
         }
    }
    
    public class B {
          public static void main (String[] args) {}
    }
    
    你明白了…Regex可能总是被愚弄,以为他们发现了一些你并不真正想要的东西。你必须依靠更高级的库来解析



    我同意J.F.Sebastian的回答。

    那么字符串在哪里?显示您的代码和不起作用的内容。我只是想提取包含主方法的类名,以便使用子流程运行
    javac
    命令。您提供的示例没有基类,因为它没有扩展任何内容。因此您只需要类name?关于
    re.findall('class(.*),a)
    ?类名后的空格是可选的,因为这是完全合法和常见的
    class MyClass{…
    ,因此您的方法在很多情况下都会失败。很抱歉,我刚刚离开:)它不工作,如果我在循环中打印
    I
    ,它会打印整个代码。@user2444327不打印
    I
    。正如我在回答中所说,
    print(re.search('class(\w*),I.group(1))
    。我正在用它打印。真的吗?让我再测试一次。这似乎有效,但我想知道它是否太过杀伤力。它是否足够快,就像regex一样?@user2444327:这取决于。测量时间性能,看看它在您的情况下是否足够快。这可能是一个杀伤力过大的问题,但如果对依赖项没有限制,那么它就更容易了要将
    javalang
    添加到您的
    requirements.txt
    ,请使用我提供的代码,不要考虑它。另一方面,如果输入很简单,请编写一个简单的正则表达式,并在必要时根据具体情况进行扩展。该类不必公开(如问题中的代码示例所示),您甚至可以有@J.F.Sebastian yes,这是真的。但是如何使用
    subprocess
    执行该文件,因为无法从该源代码中获取文件名?文件名将始终与该文件中的公共类相同,并且执行该文件将导致调用
    main
    ,而不考虑它在哪个类中。单击链接。它明确显示了在这种情况下如何执行代码的示例。无论如何,源代码不在OPs case的任何文件中。@J.F.Sebastian如果不在文件中,您将如何使用
    subprocess
    执行该Java代码?例如,将其保存到文件中。我看不出您的注释与我的第一个com有什么关系你能详细说明它与“类不必是公共的(如问题中的代码示例所示),甚至可以有多个带有public static main()方法的类”有什么关系吗?