Regex用于使用命令提示符获取两个文本之间的文本



我正在尝试使用命令提示符和findstr命令提取html文件中body标记中的内容。我的html如下

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AdminWeb</title>
  <base href="/wwwroot/admin-web/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body><app-root></app-root><script src="/wwwroot/admin-web/runtime.js"></script><script src="/wwwroot/admin-web/file1.js" nomodule></script><script src="/wwwroot/admin-web/file2.js"></script><script src="/wwwroot/admin-web/styles.js"></script><script src="/wwwroot/admin-web/vendor.js"></script><script src="/wwwroot/admin-web/main.js"></script></body>
</html>

我想要的是

<app-root></app-root>
<script src="/wwwroot/admin-web/runtime.js"></script><script src="/wwwroot/admin-web/file1.js" nomodule></script><script src="/wwwroot/admin-web/file2.js"></script><script src="/wwwroot/admin-web/styles.js"></script><script src="/wwwroot/admin-web/vendor.js"></script><script src="/wwwroot/admin-web/main.js"></script>

我正在尝试使用正则表达式。

findstr /R (?<=<body>)(.*)(?=</body>)  test.html

但现在这是在命令提示符下工作的。但是这个正则表达式在js中工作。

提前谢谢。

首先,findstr不支持现代正则表达式引擎提供的所有酷的正则表达式功能。特别是最新的兼容JavaScript ECMAScript2018+的引擎,如Chrome、Node.js等。因此,说">this regex在js中工作"并不意味着相同的模式在其他地方也能工作。它在findstr中肯定不起作用。

你可以采取艰难的方式,继续学习如何为此编写批处理脚本。然而,对于其他内置的Windows应用程序,有一种更简单的方法。

我强烈建议使用Powershell,因为它提供了.NET提供的许多功能。

在这里,打开PowerShell控制台并使用

$pathToFile = 'c:......you_file.txt'
$output_file = 'c:......you_file_out.txt' 
$rx = '(?s)(?<=<body>).*?(?=</body>)'
Get-Content $pathToFile -Raw | Select-String $rx -AllMatches | % { $_.Matches } | % { $_.Value } > $output_file

注意:最好使用IE自动化来处理HTML。

$output_file = 'c:......you_file_out.txt'
$url = 'http://your_site_here.tld/...'
$ie = New-Object -comobject "InternetExplorer.Application"
$ie.visible = $true
$ie.navigate($url)
while ($ie.Busy -eq $true -Or $ie.ReadyState -ne 4) {Start-Sleep 2}
$doc = $ie.Document
$tags = $doc.getElementsByTagName("body")
$tags[0].innerHTML > $output_file

Windows 10 64位。PowerShell 5.1

使用PowerShell 5.1匹配正则表达式分析local\remote html。

输出正文标记之间的所有内容。不要在结果中包含<body>标记。请参阅下面的本地/远程文件处理。请参阅下面查找任何<tag></tag>的第一个实例之间的任何内容。

贪婪和懒惰的量词解释

regex101.com是您的朋友。

从不使用(.?|\n(,始终使用(?s(.*?

复制并粘贴到PowerShell 5.1中。它将输出<body></body>之间的所有内容。结果输出两次,一次不带body标记,一次带。

$testhtml = @'
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>AdminWeb</title>
<base href="/wwwroot/admin-web/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script src="/wwwroot/admin-web/runtime.js"></script><script src="/wwwroot/admin-web/file1.js" nomodule></script>
<script src="/wwwroot/admin-web/file2.js"></script><script src="/wwwroot/admin-web/styles.js"></script>
<script src="/wwwroot/admin-web/vendor.js"></script><script src="/wwwroot/admin-web/main.js"></script>
</body>
</html>
'@
$testhtml -match '(?s)(?<=<body>).*?(?=</body>)';$matches[0] 
$testhtml -match '(?s)(<body>).*?(</body>)';$matches[0] 

命令可以写入:

[regex]::matches($testhtml,'(?s)(?<=<body>).*?(?=</body>)').Value
[regex]::matches($testhtml,'(?s)(<body>).*?(</body>)').Value

使用三个不同的命令处理本地文件。输出不包括正文标签:

(gc -Raw test.html) -match '(?s)(?<=<body>).*?(?=</body>)';$matches[0] 
[Regex]::Matches((gc -Raw test.html), '(?s)(?<=<body>).*?(?=</body>)').Value
gc test.html -Raw | Select-String '(?s)(?<=<body>).*?(?=</body>)' -AllMatches | % { $_.Matches } | % { $_.Value }

输出到results.html:

gc test.html -Raw | Select-String '(?s)(?<=<body>).*?(?=</body>)' -AllMatches | % { $_.Matches } | % { $_.Value } | sc results.html 

不带正文标记和带正文标记的远程url:

$testhtml = Invoke-WebRequest -Uri http://www.pgatour.com
$testhtml -match '(?s)(?<=<body>).*?(?=</body>)'
$matches[0]
$testhtml -match '(?s)(<body>).*?(</body>)'
$matches[0]

不带正文标记和带正文标记的远程url。输出到results.html:

$testhtml = Invoke-WebRequest -Uri http://www.pgatour.com
$testhtml -match '(?s)(?<=<body>).*?(?=</body>)'
$matches[0] | sc results.html
$testhtml -match '(?s)(<body>).*?(</body>)'
$matches[0] | sc results.html

任何标签和/tag 的第一个实例之间的远程url

$testhtml = Invoke-WebRequest -Uri http://www.pgatour.com
$testhtml -match '(<div class="success-message">)(?s).*?(</div>)'
$matches[0]
Invoke-WebRequest -Uri http://www.pgatour.com | sc results.html
(gc -raw results.html) -match '(<div class="success-message">)(?s).*?(</div>)'
$matches[0] 

按类名的远程url。这些工作,但不是很有成效。请参阅使用Powershell 解析HTML网页

$response = Invoke-WebRequest -Uri http://www.pgatour.com
$response.ParsedHtml.body.getElementsByClassName('success-message')
$( $response.ParsedHtml.getElementsByTagName('div') | ?{$_.className -eq 'success-message'} ).outerHTML 
$( $response.ParsedHtml.body.getElementsByTagName('div') | Where {$_.getAttributeNode('class').Value -eq 'success-message'} ).outerHTML