【问题标题】:How return contents of method in txt file如何在txt文件中返回方法的内容
【发布时间】:2022-01-18 02:11:39
【问题描述】:

我正在尝试编写一个正则表达式来返回方法名称和以下方法名称之间的方法内容。我将进一步解析我正在提取的信息。我怎么做?到目前为止,我已经开始从方法名称中获取信息,但不知道如何让它停止在以下方法名称处。任何其他想法将不胜感激。

这将返回匹配字符串方法名称的行s(但我想要整个方法):

$contents = Get-Content $codePath | Select-String -Pattern "$methodNameToReturn.*" -AllMatches

这是我试图让它结束以下方法返回的字符串的地方,但它没有找到任何东西:

Get-MethodContents -codePath $File[0] -methodNameToReturn "GetStatusFromCode" -followingMethodName "SkipPage"

Function Get-MethodContents{
[cmdletbinding()]
Param ( [string]$codePath, [string]$methodNameToReturn, [string]$followingMethodName)
Process
{
    $contents = ""
    Write-Host "In GetMethodContents method File:$codePath method:$methodNameToReturn followingMethod:$followingMethodName"  -ForegroundColor Green
    #Switch -regex (Get-Content -Path $codePath)
    #{
    #'^(.*)/s'{$contents=$switch.current}
    #}
    $contents = Get-Content $codePath | Select-String -Pattern "($methodNameToReturn.*$followingMethodName)" -AllMatches
    Write-Host "File Contents Found: $contents" -ForegroundColor Cyan
}#End of Process
}#End of Function

这是尝试匹配的示例代码(重要的是我得到了 GetStatusFromCode 方法中的内容以进一步解析):

...
bool ClassName::GetStatusFromCode(                DWORD              errorCode,
                                                  TCHAR              *errorStr,
                                                  DWORD              &outError,
                                                  COM_ERROR_SEVERITY &outSeverity,
                                                  TCHAR              *outDevStr)
{

    m_bRestart = TRUE;

    BYTE MinorCode = 0;

    // Get and check width
    DWORD dwLength = 0;
    BYTE buff[ 2 ] = {0};
    
    //
    if ( chcusb_getInfo( (WORD)kPINFTAG_SVCINFO, buff,  &dwLength ) == FALSE ) 
    {
        // Error
    }

    MinorCode = buff[1];


    switch( errorCode ) 
    {
        //case kRESULT_NOERROR:                     
        case kRESULT_MEMFULLERR:
            //code
            _sprintf(outDevStr, _T("8000 - (Comm Err)"), errStr);
            outError = errVar;
            break;

        case kRESULT_USBNOTFOUND:                   
            //code
            _sprintf(outDevStr, _T("8001 - (Comm 1 Err)"), errStr);
            outError = errVar;
            break;
        default:
            // Maybe communication error
            
            break;
    }

    m_dwErrorCode = outError;

    if ( m_bRestart == TRUE )
    {
        return true;
    }
    else
    {
        return false;
    }
}


////////////////////////////////////////
//
// METHOD NAME:     SkipPage
//
////////////////////////////////////////
bool ClassName::SkipPage( GUID JobID, DWORD dwPageNum )
...

这是我寻找更多信息的地方:

match characters across multiple lines

extract string in text file

我的问题是如何完全提取该方法名称的内容?我不在乎它是否包含以下MethodName,但它需要获取多行,直到感兴趣的方法的结束文本,methodNameToReturn。是的,我知道这样做很奇怪,但这就是我们所要求的。这是 PowerShell 5.1。

编辑:我退出了 powershell 文件,看起来它仍在查找文件,但现在使用任何一个正则表达式都找不到任何内容。

【问题讨论】:

  • 如果您愿意编写更多代码,您可以获取所有行,遍历它们直到找到与第一个方法名称匹配的行,然后遍历以下行,将它们打印出来, 直到你得到第二个名字的匹配。
  • 我不想打印出来,我想以字符串的形式从 method1 返回到 method2。然后我将从案例陈述中解析出一些东西。现在我没有从我的正则表达式中返回任何东西,所以这是一个开始。
  • 然后,您可以将它们收集在一个列表、一个数组或一个大字符串中,而不是打印出来。
  • 好吧,一旦我将方法内容转换为字符串,我会将案例内容解析为列表或数组。现在我的正则表达式什么也没返回。就像我说的,方法内容需要进入一个大字符串才能开始。
  • @adv12 我很欣赏任何如何做到这一点的例子......

标签: regex powershell


【解决方案1】:

首先,要匹配多行,您必须获取文件的“原始”内容。 Get-Content 默认返回一个字符串列表,但 -Raw 给你一个可以匹配的字符串:

$contents = Get-Content $codePath -Raw

然后,要跨多行进行正则表达式,您必须捕获行尾字符。 .* 不包括行尾,所以我在 windows 文件上使用 [\s\S]* 来代替。我还从您的示例中添加了Classname::,因为它似乎是一个开始/结束的好地方:

# -match usually returns true/false, so suppress
$null = $contents -match "(Classname::$methodNameToReturn[\s\S]*)Classname::$followingMethodName"

# Return the contents of the first capture group () as a single string
$Matches.Item(1)

更多关于-Match的信息

【讨论】:

  • 非常感谢!!! :)
  • 我试图了解 $Matches.Item(1) 是什么。当我写主机“Matches.Item(1)”时,它会打印 System.Collections.Hashtable.Item(1)。这似乎不是一个字符串。如何进一步解析 case 语句的内容?
【解决方案2】:

不愿编写成熟的 C++ 解析器,一个有用的启发式方法是使用方法体,直到您到达对应于开头 { 的关闭 } - 这种方法的好处是 PowerShell 的正则表达式运算符可以为您找到它们!

.NET 正则表达式引擎支持称为balancing groups 的东西,它允许我们跟踪我们遇到了多少个左括号,并在每次遇到相应的右括号时递减计数器:

Select-String -Path $codePath -Pattern "(?s)$methodNameToReturn\s*\(.*\)\s*\{(?:[^{}]|(?<bracket>\{)|(?<-bracket>\}))+(?(bracket)(?!))\}"

【讨论】:

    【解决方案3】:

    当然,您也可以使用 Select-String 来做到这一点,但正则表达式可能只是:

    $contents = [regex]::Match($codePath,"(?s)($methodNameToReturn.*\})(.*?$followingMethodName)").Groups[1].Value
    

    可能也可以稍微清理一下正则表达式,但这些捕获可以满足您的需求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-04
      • 1970-01-01
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      • 2014-08-30
      相关资源
      最近更新 更多