Regex 替换文件中第一个括号之前的所有连字符
我正在尝试使用sed或perl替换第一个实例之前文件中出现的所有连字符) 到目前为止,我有以下内容替换了文件中的所有连字符,但我无法使其仅匹配到“;”的第一个实例 进一步资料: 我正在尝试从已生成的create table SQL中删除无效的连字符,我们有1k+个文件要处理,但我使用的任何连字符都会替换所有连字符 要清除的文本示例:Regex 替换文件中第一个括号之前的所有连字符,regex,perl,sed,pattern-matching,Regex,Perl,Sed,Pattern Matching,我正在尝试使用sed或perl替换第一个实例之前文件中出现的所有连字符) 到目前为止,我有以下内容替换了文件中的所有连字符,但我无法使其仅匹配到“;”的第一个实例 进一步资料: 我正在尝试从已生成的create table SQL中删除无效的连字符,我们有1k+个文件要处理,但我使用的任何连字符都会替换所有连字符 要清除的文本示例: CREATE TABLE e_00_90 ( Last_Name nvarchar(50), Initials nvarchar(3), Company_D
CREATE TABLE e_00_90 (
Last_Name nvarchar(50),
Initials nvarchar(3),
Company_Division nvarchar(50),
Status nvarchar(12),
Ckeyword5 nvarchar(15),
Value_of_Contract_-_Overh decimal(20,2)
);
insert into export_00_90 values ('Sample-One', 'R', 'Div 1', 'Expired', 'ANONYTR', 5000);
insert into export_00_90 values ('Sample Two', 'R', 'Div_2', 'Expired', 'WISHBONE', 13000);
我只需要创建表块就可以删除连字符。(?:(?!PAT)。*
是要PAT
,正如[^CHAR]
是要CHAR
,所以
s/\G (?: (?! \); | - ) . )* \K - /_/xsg
备选方案:
s/\G (?: (?! \); ) [^-] )* \K - /_/xg
最快:
s/\G (?: [^)-]++ | \)(?!;) )* \K - /_/xg
使用GNU时:
sed -E ':a;s/^([^)]*)-([^)]*\);)/\1_\2/;ta;'
[编辑]使用awk:
awk -v RS=');' -v ORS=');' '/^CREATE TABLE/{gsub("-","_")}1'
使用perl:
perl -pe'BEGIN{$/=");"} /^CREATE TABLE/&&y/-/_/'
对于sed:
sed '/^CREATE TABLE/{:;/);/!{N;b};y/-/_/;}'
sed -E ':;s/^(([^)-]|\)[^;-])*\)*)-/\1_/;t'
awk和perl的方法是相同的,它们使用记录分隔符)代码>,检查此字符是否以“createtable”开头,并将每个连字符转换为下划线
sed版本没有太大的不同,只是您需要自己构建文本块,将每一行追加到)代码>。(注意,这种方式假定之后没有更多的代码)代码>在同一行中):
{
:#定义一个空标签
/);/!(如果);不匹配
{
N#在模式空间中添加换行符
去标签那儿
}
y/-/#翻译
}
[旧答案:只能按行操作]
对于sed:
sed -E ':;s/^(([^)-]|\)[^;-])*\)*)-/\1_/;t'
或者使用perl:
perl -pe's/.*?\);|.+/$&=~y|-|_|r/e'
(这种方式匹配所有,直到第一个)
或字符串的结尾,然后使用y//
)将匹配中的每个连字符转换为下划线。我不会尝试使用神奇的正则表达式来处理它,而是:
#!/usr/bin/env perl
use strict;
use warnings;
while ( <DATA> ) {
if ( m/CREATE TABLE/ .. /\);/ ) {
s/-/_/g;
}
print;
}
__DATA__
CREATE TABLE e_00_90 (
Last_Name nvarchar(50),
Initials nvarchar(3),
Company_Division nvarchar(50),
Status nvarchar(12),
Ckeyword5 nvarchar(15),
Value_of_Contract_-_Overh decimal(20,2)
);
insert into export_00_90 values ('Sample-One', 'R', 'Div 1', 'Expired', 'ANONYTR', 5000);
insert into export_00_90 values ('Sample Two', 'R', 'Div_2', 'Expired', 'WISHBONE', 13000);
试试的/^((?:(?!\);)*)-\)/$1_);/'代码>不错。我不知道您可以在没有标签的情况下使用t
命令。@SLePort:事实上,您需要一个标签,但这个标签的名称是空的。谢谢。这两种方法似乎都可以将所有连字符转换为下划线,即使是在第一次使用“;”之后的连字符@uint32:我回答了你问题的第一个版本,没有多行示例。因此,我的答案和其他答案都是按行设计的。现在你的问题完全不同了。@Casimir et Hippolyte:谢谢你的意见。很抱歉,我最初的问题并不像应该的那么清楚。
perl -pi -e 'm/CREATE TABLE/ .. /\);/ && s/-/_/g' 00-90.sql