在powershell中,[text . regulareexpressions .]RegexOptions]::Ig



尝试采用vhdl或ada源文件,匹配关键字,并将其替换为列表中的关键字。然而,我的正则表达式不能与忽略递增和多行一起工作,替换$1和$2。下面是我的代码。什么好主意吗?谢谢。

$ErrorActionPreference = 'Stop'
$script:regop_gi = [Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [Text.RegularExpressions.RegexOptions]::Multiline
function ReplaceKeyWords {
param(
[string]$text, 
[string[]]$keywords
) #returns string

for ($k = 0; $k -lt $keywords.Length; $k++) {
$r0 = "([^a-zA-Z0-9_@]|^)" + $keywords[$k] + "([^a-zA-Z0-9_]|$)"
$r1 = [regex]::new($r0, $script:regop_gi)
$text = $text.replace($r1, "$1" + $keywords[$k] + "$2")
}
return $text
}

$vhdl = @()
$vhdl += "library ieee;"
$vhdl += "use ieee.std_logic_1164.all;"
$vhdl += "   use std.textio.all;"
$vhdl += ""
$vhdl += ""
$vhdl += "entity mydesign is"
$vhdl += "    port("
$vhdl += "      clk:in std_logic;"
$vhdl += "  rst:in std_logic;"
$vhdl += "         xyz  : in    std_logic_vector(7 downo 0);"
$vhdl += "   abc:out std_logic_vector(7 downto 0)"
$vhdl += "    )"
$vhdl += "end entity"
$vhdl += ""
$vhdl += "architecture beh of mydesign is"
$vhdl += "begin"
$vhdl += "    process(clk,           rst)"
$vhdl += "  begin"
$vhdl += "        if (rst) then"
$vhdl += "           abc        <=             (others=>'0');"
$vhdl += " else (rising_edge(clk)) then"
$vhdl += "    abc        <=             xyz;"
$vhdl += "       end if;"
$vhdl += "                  end process;"
$vhdl += "end architecture;"
$vhdl += ""
$vhdl_lines = $vhdl -join "`n"

$KeyWords = @(
"BEGIN"
"END"
"ENTITY"
"ARCHITECTURE"
)
$newtext = ReplaceKeyWords -text $vhdl_lines -keywords $Keywords
write-host $newtext

以下语句在多个层面上都是错误的:

$text = $text.replace($r1, "$1" + $keywords[$k] + "$2")

  • 考虑$text[string]类型,.replace()是指System.String.Replace()方法,该方法对逐字字符串进行操作,而不是对正则表达式进行操作。

  • 使用可扩展(插入)字符串,如"$1""$2",导致$1$2被解释为PowerShell变量引用


您可能正在使用基于regex的-replace操作符寻找以下内容:

$text = $text -replace ('b{0}b' -f $keywords[$k]), $keywords[$k]

PowerShell的regex操作默认是大小写不敏感的,并且,考虑到您的替换不跨行IgnoreCaseMultiLineregex选项都不需要。


同样,在PowerShell (Core) 7+中,您可以简化代码如下,利用能够传递脚本块作为替换操作数的优势:

# Use a here-string to define your string.
$vhdl_lines = @'
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;

entity mydesign is
port(
clk:in std_logic;
rst:in std_logic;
xyz  : in    std_logic_vector(7 downo 0);
abc:out std_logic_vector(7 downto 0)
)
end entity
architecture beh of mydesign is
begin
process(clk,           rst)
begin
if (rst) then
abc        <=             (others=>'0');
else (rising_edge(clk)) then
abc        <=             xyz;
end if;
end process;
end architecture;
'@
# The array of keywords to upper-case.
$keyWords = @(
"BEGIN"
"END"
"ENTITY"
"ARCHITECTURE"
)
# Replace the keywords with their uppercase versions.
$vhdl_lines -replace ('b(?:{0})b' -f ($keyWords -join '|')),
{ $_.Value.ToUpper() }

最新更新