如何使用正则表达式删除特定单词之间的空格?

时间:2019-03-14 10:53:25

标签: c# regex

我想从字符串中的特定单词中删除空格。例如,将以下查询视为输入字符串

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");

那么可以创建一个正则表达式来仅删除字符串中特定单词的空格吗?

任何建议都值得赞赏。

2 个答案:

答案 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())和任何其他组合匹配。

测试和解释:https://regex101.com/r/28nfTE/1

答案 1 :(得分:0)

使用Replace的MatchEvaluator的功能来处理实际的脏活。

使用\s([LR])TRIM\s的基本模式,我们将用空格标识目标TRIM单词。在该模式下,我们将创建一个子组,该子组将通过LR标识需要提供什么,并在.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  )