尝试采用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操作默认是大小写不敏感的,并且,考虑到您的替换不跨行,IgnoreCase
和MultiLine
regex选项都不需要。
同样,在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() }