正则表达式使用ruby从文件中提取方法名称

时间:2016-03-05 07:47:48

标签: ruby regex

我必须在很多文件中进行一些更改,因此我正在编写一个Regex脚本,它将打开所有这些文件并进行更改。我已经完成了所有工作,但只需要1 ... @Test(priority = 10) @RunAsClient public void methodName(){ ... } ... @Test(priority = 20) public void otherMethodName(){ ... } ... 来帮助查找带有特定注释的所有方法,因为这些文件来自Java。

文件的示例部分:

result = ['methodName', 'otherMethodName']

我需要找到所有这些带有这种注释的方法。 结果应该是:

first_regex_pattern = /(?<=@Test\(priority = \d\d\)\n@RunAsClient\npublic void )([^\(]+)/

我可以提取一个或另一个,但不能同时提取两个。为了提取第一种,我创建了一个正则表达式。

second_regex_pattern = /(?<=@Test\(priority = \d\d\)\npublic void )([^\(]+)/

first regex

并提取第二种类型

activityLevel

second regex

我需要结合我的解决方案

3 个答案:

答案 0 :(得分:1)

str.scan /(@Test\(priority = \d{2}\)\n)?(@RunAsClient\n)?(\w+\s+\w+\s+\w+)/
#⇒ [
#  [0] [
#    [0] "@Test(priority = 10)\n",
#    [1] "@RunAsClient\n",
#    [2] "public void metodName"
#  ],
#  [1] [
#    [0] "@Test(priority = 20)\n",
#    [1] nil,
#    [2] "public void otherMethodName"
#  ]
# ]

要求的结果:

str.scan(/(@Test\(priority = \d{2}\)\n)?(@RunAsClient\n)?(\w+\s+\w+\s+\w+)/)
   .map(&:last)
   .map { |e| e.split(' ').last }                         
#⇒ [
#  [0] "metodName",
#  [1] "otherMethodName"
# ]

答案 1 :(得分:1)

str =<<_
@Test(priority =10)
@RunAsClient
public void metodName(){
   ...
}

   ...

@Test(priority =     20)
public void otherMethodName(){
   ...
}
...
_

r = /
    \@Test\(\s*priority\s*=\s*\d+\s*\)\s*\n  # Match string
    (?:\@RunAsClient\n)?  # Optionally match string
    (?:\w+\s+)+           # Match (word, >= 1 spaces) >= 1 times
    \K                    # Forget everything matched so far
    \w+                   # match word
    (?=                   # begin positive lookahead
      (?:\([^)]*\)\s*\{)  # match paren-enclosed expression, >= 0 spaces, {
      |                   # or
      (?:\s*\{)           # match >= 0 spaces, {
    )                     # end positive lookahead
    /x                    # extended/free-spacing regex definition mode

str.scan r
  #=> ["metodName", "otherMethodName"]

答案 2 :(得分:0)

mudasobwa的答案看起来很棒,但是如果你的函数只有一个类型而没有关键字public,那么正则表达式应该是:

str.scan(/(@Test\(priority = \d{2}\)\n)?(@RunAsClient\n)?\w+\s+(\w+\s+)?(\w+)/).map(&:last)

这也有点短

如果您只对函数名称感兴趣,而不是对上下文行中的数据感兴趣,那么这个正则表达式更简单 - 它匹配函数定义的签名:

 str.scan(/\w+\s+(\w+\s+)?(\w+)\(\)\s?\{/).map(&:last)

这会查找类型,方法名称和()后跟可选空格,然后是{