我想从字符串中的特定单词中删除空格。例如,将以下查询视为输入字符串
SELECT LTRIM ( RTRIM ( [EMPOYEE_NAME] ) ), LTRIM ( RTRIM ( [EMPOYEE_ADDR] ) ), LTRIM ( RTRIM ( [EMPOYEE_TYPE] ) ) FROM EMPLOYEE WHERE ( EMPLOYEE_ID = @EMPLOYEE_ID )
现在,我要删除LTRIM,RTRIM括号和其中的内容之间的空格,而不是整个字符串。
因此最终输出应为
SELECT LTRIM(RTRIM([EMPOYEE_NAME])), LTRIM(RTRIM([EMPOYEE_ADDR])), LTRIM(RTRIM([EMPOYEE_TYPE])) FROM EMPLOYEE WHERE ( EMPLOYEE_ID = @EMPLOYEE_ID )
我尝试了以下解决方案,但是它将替换所有空格-
var source = "SELECT LTRIM ( RTRIM ( [EMPOYEE_NAME] ) ), LTRIM ( RTRIM
( [EMPOYEE_ADDR] ) ), LTRIM ( RTRIM ( [EMPOYEE_TYPE] ) ) FROM EMPLOYEE
WHERE ( EMPLOYEE_ID = @EMPLOYEE_ID )";
source = Regex.Replace(source, "\\s(\\s?)\\s*", "$1");
那么可以创建一个正则表达式来仅删除字符串中特定单词的空格吗?
任何建议都值得赞赏。
答案 0 :(得分:1)
我会先行使用lookbehind:
var source = "SELECT LTRIM ( RTRIM ( [EMPOYEE_NAME] ) ), LTRIM ( RTRIM ( [EMPOYEE_ADDR] ) ), LTRIM ( RTRIM ( [EMPOYEE_TYPE] ) ) FROM EMPLOYEE WHERE ( EMPLOYEE_ID = @EMPLOYEE_ID )";
source = Regex.Replace(source, @"((?<=LTRIM)(\s)|(?<=RTRIM)\s+(?=\()|(?<=\()\s+|\s+(?=\)))", "");
Console.WriteLine(source);
输出:
SELECT LTRIM(RTRIM([EMPOYEE_NAME])), LTRIM(RTRIM([EMPOYEE_ADDR])), LTRIM(RTRIM([EMPOYEE_TYPE])) FROM EMPLOYEE WHERE (EMPLOYEE_ID = @EMPLOYEE_ID)
测试和解释:https://regex101.com/r/agq0V5/1
注意:为了简化此操作,它还会删除WHERE
大括号内的空格,这样不好吗?
编辑
这里的解决方案链组在WHERE
括号内没有匹配的空格。
var source = "SELECT LTRIM ( RTRIM ( [EMPOYEE_NAME] ) ), LTRIM ( RTRIM ( [EMPOYEE_ADDR] ) ), LTRIM ( RTRIM ( [EMPOYEE_TYPE] ) ) FROM EMPLOYEE WHERE ( EMPLOYEE_ID = @EMPLOYEE_ID )";
source = Regex.Replace(source, @"(LTRIM)(\s*)(\()(\s*)(RTRIM)(\s*)(\()(\s*)([^ ]*)(\s*)(\))(\s*)(\))", "$1$3$5$7$9$11$13");
Console.WriteLine(source);
输出:
SELECT LTRIM(RTRIM([EMPOYEE_NAME])), LTRIM(RTRIM([EMPOYEE_ADDR])), LTRIM(RTRIM([EMPOYEE_TYPE])) FROM EMPLOYEE WHERE ( EMPLOYEE_ID = @EMPLOYEE_ID )
编辑2
另一种解决方案是删除FROM
部分,然后替换括号附近的空格,然后添加缺少的部分。
var source = "SELECT LTRIM ( RTRIM ( [EMPOYEE_NAME] ) ), LTRIM ( RTRIM ( [EMPOYEE_ADDR] ) ), LTRIM ( RTRIM ( [EMPOYEE_TYPE] ) ) FROM EMPLOYEE WHERE ( EMPLOYEE_ID = @EMPLOYEE_ID )";
var from_part = Regex.Match(source, @"FROM.*");
var partial_source = Regex.Replace(source, @"FROM.*", "");
source = Regex.Replace(partial_source, @"(\s+(?=\))|(\s+(?=\())|(?<=\()(\s+))", "");
var final_string = source + from_part.Value;
Console.WriteLine(final_string);
输出:
SELECT LTRIM(RTRIM([EMPOYEE_NAME])), LTRIM(RTRIM([EMPOYEE_ADDR])), LTRIM(RTRIM([EMPOYEE_TYPE])) FROM EMPLOYEE WHERE ( EMPLOYEE_ID = @EMPLOYEE_ID )
这也将与LTRIM()
RTRIM()
LTRIM(RTRIM())
RTRIM(LTRIM())
和任何其他组合匹配。
答案 1 :(得分:0)
使用Replace的MatchEvaluator的功能来处理实际的脏活。
使用\s([LR])TRIM\s
的基本模式,我们将用空格标识目标TRIM单词。在该模式下,我们将创建一个子组,该子组将通过L
或R
标识需要提供什么,并在.group[1].value
处找到。因此,该小组将告诉我们是否要放入{SP}LTRIM
或无空格RTRIM
。
string txt = "SELECT LTRIM ( RTRIM ( [EMPOYEE_NAME] ) ), LTRIM ( RTRIM ( [EMPOYEE_ADDR] ) ), LTRIM ( RTRIM ( [EMPOYEE_TYPE] ) ) FROM EMPLOYEE WHERE ( EMPLOYEE_ID = @EMPLOYEE_ID )";
Regex.Replace(txt, @"\s([LR])TRIM\s", new MatchEvaluator( mtch => {
return (mtch.Groups[1].Value == "L") ? $" LTRIM" : "RTRIM";
} ));
返回
SELECT LTRIM(RTRIM( [EMPOYEE_NAME] ) ), LTRIM(RTRIM( [EMPOYEE_ADDR] ) ), LTRIM(RTRIM( [EMPOYEE_TYPE] ) ) FROM EMPLOYEE WHERE ( EMPLOYEE_ID = @EMPLOYEE_ID )