Java 段落条件嵌套正则表达式(递归)
我需要一个与以下段落匹配的正则表达式:'&Start a'(示例文本中的第一个)直到'&end a'(示例文本的最后一个结尾)。问题是有时没有明确指定“&end a”,有时写为“&end”。当您有“&Start b”和“&end b”(有时也是“&end”,因此会产生混淆)时,问题就更大了 此正则表达式的目标示例块是(很抱歉将其作为代码块): 这两行很好地隔离了“开始a”和“结束”段落,但当其他“开始Y”行出现在这两行之间时,脚本会变得混乱。 我可能会用一些If语句跳过不需要的块。。。下面是一个更复杂的案例处理方法:Java 段落条件嵌套正则表达式(递归),java,regex,powershell,if-statement,paragraph,Java,Regex,Powershell,If Statement,Paragraph,我需要一个与以下段落匹配的正则表达式:'&Start a'(示例文本中的第一个)直到'&end a'(示例文本的最后一个结尾)。问题是有时没有明确指定“&end a”,有时写为“&end”。当您有“&Start b”和“&end b”(有时也是“&end”,因此会产生混淆)时,问题就更大了 此正则表达式的目标示例块是(很抱歉将其作为代码块): 这两行很好地隔离了“开始a”和“结束”段落,但当其他“开始Y”行出现在这两行之间时,脚本会变得混乱。 我可能会用一些If语句跳过不需要的块。。。下面是一个
junk text
&Start a <
fulfilling text
fulfilling text
&Start b
&Start c
&end
fulfilling text
&end
&end <
junk text
对于这个问题,纯正则表达式解决方案可能不是最好的解决方案。这可能是可以做到的,但它可能会非常复杂和不可读。为此,我将使用一个简单的解析器。例如:
function Remove-TextGroup {
param(
[Parameter(Mandatory=$true)]
[string[]]$Data,
[Parameter(Mandatory=$true)]
[string]$GroupID
)
$Data | ForEach-Object -Begin { $ignore = $false; $levels = 0 } -Process {
#Start ignoring text after we've found the trigger
if($_ -match "^&start $GroupID") { $ignore = $true }
#Track nested groups
elseif($ignore) {
if ($_ -match '^&start') { $levels++ }
elseif ($_ -match '^&end') {
if($levels -ge 1) { $levels-- }
#If no nesting, we've hit the end of our targeted group. Stop ignoring
else { $ignore = $false }
}
}
#Write line
else { $_ }
}
}
用法:
$data = @"
junk text
&Start a <
fulfilling text
fulfilling text
&Start b
&Start c
&end
fulfilling text
&end
&end <
junk text
"@ -split "`n" | ForEach-Object { $_.trim() } |
#Remove empty lines
Where-Object { $_ }
Remove-TextGroup -Data $data -GroupID a
#Or to read from file..
#$data = Get-Content -Path Myfile.txt
Remove-TextGroup -Data $data -GroupID a
如果文件很大,我会优化上面的示例,使用
streamreader
读取文件。你不能使用regex来读取文件,你需要一个解析器。不太清楚,你看,你需要这样的东西吗?它是Java还是Powershell?Java。不抱歉,“您希望它在匹配的$end
”标记处结束,而中间可能有多个开始/结束标记。就像我说的,这在正则表达式中是不可能的(保持你的理智)@WiktorStribiżew-这将适用于&Start a
,但不适用于$Start b
a中的测试也应该被删除。我将尝试实施您的解决方案。有没有办法创建可以从批处理文件运行的powershell脚本?为什么?只在a组。你不是说你想跳过b组和c组吗?如果我们忽略“a中的测试”,那么我们也可以在开始b时停止。在“结束a”之前的所有内容都必须删除。即使它在a区。对不起,我的解释……我以为你想保留a组。您是否要删除组a的内容(不是开始和结束)并保留文档的其余部分?如果是的话,应该在问题中更好地加以说明。所需的输出示例也会有所帮助。我希望完全删除组A,包括开始A及其相应的结束。我稍后会更新这个问题。再次抱歉。
#@ -split "`n" | ForEach-Object { $_.trim() } |
$files = Get-ChildItem "$PSScriptRoot" # root path
for($i=0; $i -lt $files.Count; $i++){
#iterate through files from the current folder.
$data = Get-Content -Path $files[$i].FullName
# parse DisabledFeatures.txt file as array of strings (1 string per line of the file)
$feature = Get-Content DisabledFeatures.txt
#iterate for each string entry in $feature array (read from txt file)
for($counter=0; counter -lt $feature.Count; counter++){
#retrieve array value to use it in the main algorythm
$groupID = "$feature"
$data | ForEach-Object -Begin { $ignore = $false; $levels = 0 } -Process {
#Start ignoring text after we've found the trigger
if($_ -match "^`#ifdef $groupID") { $ignore = $true }
#Track nested groups
elseif($ignore) {
if ($_ -match '^`#ifdef') { $levels++ }
elseif ($_ -match '`#endif') {
if($levels -ge 1) { $levels-- }
#If no nesting, we've hit the end of our targeted group. Stop ignoring
else { $ignore = $false }
}
}
#Write line
else { $_ }
}
}
}
function Remove-TextGroup {
param(
[Parameter(Mandatory=$true)]
[string[]]$Data,
[Parameter(Mandatory=$true)]
[string]$GroupID
)
$Data | ForEach-Object -Begin { $ignore = $false; $levels = 0 } -Process {
#Start ignoring text after we've found the trigger
if($_ -match "^&start $GroupID") { $ignore = $true }
#Track nested groups
elseif($ignore) {
if ($_ -match '^&start') { $levels++ }
elseif ($_ -match '^&end') {
if($levels -ge 1) { $levels-- }
#If no nesting, we've hit the end of our targeted group. Stop ignoring
else { $ignore = $false }
}
}
#Write line
else { $_ }
}
}
$data = @"
junk text
&Start a <
fulfilling text
fulfilling text
&Start b
&Start c
&end
fulfilling text
&end
&end <
junk text
"@ -split "`n" | ForEach-Object { $_.trim() } |
#Remove empty lines
Where-Object { $_ }
Remove-TextGroup -Data $data -GroupID a
#Or to read from file..
#$data = Get-Content -Path Myfile.txt
Remove-TextGroup -Data $data -GroupID a
junk text
junk text