1

我已经有一段时间没有接触编程了。我有一些要格式化的字符串。它们看起来像这样:

,SUM(CASE WHEN [Level] IN('4') AND Program = 1 THEN 1 ELSE 0 END) as CNT1
,SUM(CASE WHEN [Level] IN('3') AND Program = 1 THEN 1 ELSE 0 END) as CNT2
,SUM(CASE WHEN [Level] IN('2') AND Program = 1 THEN 1 ELSE 0 END) as CNT3
,SUM(CASE WHEN [Level] IN('1') AND Program = 1 THEN 1 ELSE 0 END) as CNT4
,SUM(CASE WHEN [Level] IN('0') AND Program = 1 THEN 1 ELSE 0 END) as CNT5

我想把它改成

,CNT1 = SUM(CASE WHEN [Level] IN('4') AND Program = 1 THEN 1 ELSE 0 END) 
,CNT2 = SUM(CASE WHEN [Level] IN('3') AND Program = 1 THEN 1 ELSE 0 END) 
,CNT3 = SUM(CASE WHEN [Level] IN('2') AND Program = 1 THEN 1 ELSE 0 END) 
,CNT4 = SUM(CASE WHEN [Level] IN('1') AND Program = 1 THEN 1 ELSE 0 END) 
,CNT5 = SUM(CASE WHEN [Level] IN('0') AND Program = 1 THEN 1 ELSE 0 END) 

现在我有一个multiline textbox我粘贴字符串的地方。我想单击一个按钮并将其格式化为第二个文本框。

这是我到目前为止所尝试的。但我不确定使用什么字符串函数以我想要的方式格式化它。

            List<String> Items = new List<string>();
            string frTxt;
            foreach (string lne in txtM.Lines)
            {
                frTxt = "";
                frTxt = lne;

            }  

多行文本框在哪里txtM。如果我Console.WriteLine(lne);在循环中这样做,它会成功循环。

4

5 回答 5

2

假设格式总是

,<text_1> 作为 <text_2>

以下将其转换为:

,<文本_2> = <文本_1>

txtM.Lines = txtM.Lines.Select(l => Regex.Replace(l, ",(.+) as (.+?)$", ",$2 = $1")).ToArray();

正则表达式的解释:

  • "," 和 " as " 匹配那些确切的字符串
  • "(.+)" 贪婪匹配至少一个字符,并将其捕获为第一组
  • "(.+?)" 非贪婪匹配至少一个字符并将其捕获为第二组
  • "$" 匹配行尾

作为结合贪婪和非贪婪匹配的结果,我们强制“as ...”作为最后一次出现(所以如果字符串恰好在其中的某个地方包含“as”,那无关紧要)。通过添加“$”,我们确保第二次捕获将所有内容带到行尾(否则,由于它是非贪婪匹配,它只会匹配“ as”之后的第一个字符,这不是我们想要的)。

替换只是使用正则表达式捕获的两个组构造新字符串,添加“=”。我们还在开头手动添加了“,”,因为我们的正则表达式匹配它,因此它将被替换字符串替换。(这可以克服,但可能会使正则表达式更复杂)。

于 2012-07-09T16:06:09.627 回答
1

好吧,如果它只是那里的开始和结束,你可以做

myString.Replace(",", ",CNT1 = ").Replace(" as CNT1", "");

使用内置string方法有很多方法可以做到这一点

查看字符串文档


这是一个功能齐全且经过测试的代码片段:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] strArr = 
            {
            ",SUM(CASE WHEN [Level] IN('4') AND Program = 1 THEN 1 ELSE 0 END) as CNT1",
            ",SUM(CASE WHEN [Level] IN('3') AND Program = 1 THEN 1 ELSE 0 END) as CNT2",
            ",SUM(CASE WHEN [Level] IN('2') AND Program = 1 THEN 1 ELSE 0 END) as CNT3",
            ",SUM(CASE WHEN [Level] IN('1') AND Program = 1 THEN 1 ELSE 0 END) as CNT4",
            ",SUM(CASE WHEN [Level] IN('0') AND Program = 1 THEN 1 ELSE 0 END) as CNT5",
            };

            //intellisence didn't like assignment in the foreach loop
            for(int i=0; i<strArr.Length; i++)
            {
                string cnt = Regex.Match(strArr[i], @"CNT\d+$").Value;
                strArr[i] = strArr[i].Replace(",", String.Format(",{0} = ",cnt)).Replace(String.Format(" as {0}", cnt), "");
            }

            foreach(string str in strArr)
            {
                Console.WriteLine(str);
            }

        }
    }
}
于 2012-07-09T15:57:45.330 回答
0

查看Regex.Replace与正则表达式匹配和Regex 语言

您想使用分组构造(...)来捕获插入子字符串的位置,并使用第二个构造来捕获要插入的子字符串。

于 2012-07-09T15:58:44.250 回答
0

这是非常具体的。您的输入字符串是否总是具有这种格式?在这种情况下,您可以使用以下内容:

        string s = textBox1.Text;
        var result = s.Split(',').ToList();
        result.ForEach(x =>
        {
            int removeAfter = x.LastIndexOf(" as CNT");
            string cntNum = x.Substring(x.LastIndexOf("CNT"), x.Length - 1);
            x = string.Format(",{0} = {1}", cntNum, x.Substring(0, removeAfter));
        });

但我强烈建议研究使用正则表达式进行搜索和替换。

于 2012-07-09T16:02:17.327 回答
0

我假设您正在使用带有 multines 的richTextbox,请参阅示例如何做到这一点

private void FormatLinesInTextBox()
{
    int cnt = 1;
    foreach (string line in richTextBox1.Lines)
    {
        string cntNumber = cntNumber = "CNT" + cnt;
        richTextBox1.Lines[cnt - 1] = "," + cntNumber + line.Replace(cntNumber, string.Empty);
        cnt++;
    }
}
于 2012-07-09T16:08:04.313 回答