【话题:学习交流】C#中字符串的正则表达式之反向引用、分割

_明月 2016-10-18 10:36:17
题目要求:将"我...我我..我我我我....爱爱爱..爱..爱...你你...你..你你你...",变成"我爱你"。

我个人代码如下所示:

string msg = "我...我我..我我我我....爱爱爱..爱..爱...你你...你..你你你...";
//Regex.Replace(msg, @"");
string[] strNum = Regex.Split(msg, @"\.", RegexOptions.IgnorePatternWhitespace);
//Console.WriteLine(strNum);
string msg2 = null;
for (int i = 0; i < strNum.Length; i++)
{
msg2 += strNum;
}

msg2 = Regex.Replace(msg, @"(.)\1+", "$1");

Console.WriteLine(msg2);

Console.ReadKey();




我个人在编写运行我自己的代码时遇到的问题:

在代码运行完下面一行代码(局部代码一)后,strNum数组中就没有‘.’(点号)了,如图片1所示。

局部代码一
 string[] strNum = Regex.Split(msg, @"\.", RegexOptions.IgnorePatternWhitespace);


图片1


取一空字符串msg,遍历字符串数组strNum,使strNum字符串数组中的每个元素都赋值给msg。我很奇怪的时,当将strNum数组中的每个字符赋值给msg后,msg中的内容为:我我我我我我我爱爱爱爱爱你你你你你你 ,如图片2所示。为何当msg运行下一行代码(局部代码二)后,就变成了:我.我.我.爱.爱.爱.你.你.你. ?如图片3所示。

局部代码二

msg2 = Regex.Replace(msg, @"(.)\1+", "$1");



图片2



图片3


这个是怎么回事?求指点,谢谢。


[i] 在最后分享一首我曾经分享过的诗




江山与情 两首

金庸 [现代]

千古垂名有何欢,世人谁知帝王难。

一个情字书万卷,只写恩爱是江山。

女人本是一枝花,花开四季原为他。

宁愿情郎捻成土,也不开在富贵家。



我美丽的校园





...全文
209 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
stherix 2016-10-19
  • 打赏
  • 举报
回复
变量写错了 29行的msg应该为msg2
赵4老师 2016-10-19
  • 打赏
  • 举报
回复
引用 15 楼 xuzuning 的回复:
正则也是 有限状态自动机
谬论。不然你试试用正则解一下5楼的题。
_明月 2016-10-19
  • 打赏
  • 举报
回复
引用 16 楼 stherix 的回复:
[quote=引用 4 楼 dear_Alice_moon 的回复:] [quote=引用 2 楼 stherix 的回复:] 变量写错了 29行的msg应该为msg2
嗯,是的,错误就在这里。谢谢 我想知道,你是如何发现这个错误的?我当时就一直不明白是怎么回事!我仔细想了一想自己的解题思路,思路无误,代码也无“错误”。当时,就是不知道第29行的msg应该改成msg2 。 这个msg我当时考虑的是msg2,但是可能敲代码时,一下敲成了msg! [/quote] 很容易想到把 明明已经通过split把句点全部去掉了,最后的替换结果里面居然还有句点 要么是split语句有问题,要么就是引用了不正确的中间变量了[/quote] 哦,是这样啊。谢谢
stherix 2016-10-19
  • 打赏
  • 举报
回复
引用 4 楼 dear_Alice_moon 的回复:
[quote=引用 2 楼 stherix 的回复:] 变量写错了 29行的msg应该为msg2
嗯,是的,错误就在这里。谢谢 我想知道,你是如何发现这个错误的?我当时就一直不明白是怎么回事!我仔细想了一想自己的解题思路,思路无误,代码也无“错误”。当时,就是不知道第29行的msg应该改成msg2 。 这个msg我当时考虑的是msg2,但是可能敲代码时,一下敲成了msg! [/quote] 很容易想到把 明明已经通过split把句点全部去掉了,最后的替换结果里面居然还有句点 要么是split语句有问题,要么就是引用了不正确的中间变量了
xuzuning 2016-10-19
  • 打赏
  • 举报
回复
正则也是 有限状态自动机
  • 打赏
  • 举报
回复
string.Join("", Regex.Matches("我...我我..我我我我....爱爱爱..爱..爱...你你...你..你你你...", @"[\u4e00-\u9fa5]").Cast<Match>().Select(m => m.Value).Distinct())
_明月 2016-10-19
  • 打赏
  • 举报
回复
引用 12 楼 zhao4zhong1 的回复:
要会画状态转换图。
嗯,我会记得赵老师你的这个指点的。我个人也挺喜欢绘图的。
赵4老师 2016-10-19
  • 打赏
  • 举报
回复
要会画状态转换图。
赵4老师 2016-10-19
  • 打赏
  • 举报
回复
引用 10 楼 dear_Alice_moon 的回复:
[quote=引用 9 楼 zhao4zhong1 的回复:] 参考《编译原理》中的词法分析和有限状态自动机。
《编译原理》目前刚刚学到有限自动机、无限自动机。但是,感觉没啥用。而且,这个地方,也不好学。知识点有些绕。 [/quote] 其实回想我数十年的IT生涯,《编译原理》这门课中N多知识点中也就“使用有限状态自动机做词法分析”在后来的实际工作中应用过。
_明月 2016-10-19
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
参考《编译原理》中的词法分析和有限状态自动机。
《编译原理》目前刚刚学到有限自动机、无限自动机。但是,感觉没啥用。而且,这个地方,也不好学。知识点有些绕。
赵4老师 2016-10-19
  • 打赏
  • 举报
回复
参考《编译原理》中的词法分析和有限状态自动机。
赵4老师 2016-10-19
  • 打赏
  • 举报
回复
不信的话,让谁用正则表达式解这道题。
_明月 2016-10-19
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
仅供参考:
//有字符串
//1_22_333,,4444__55555,_666666
//需要解析为
//1
//22
//333
//_
//4444
//55555
//666666
#include <stdio.h>
char s[]="1_22_333,,4444__55555,_666666";
char c,*p,*p1;
int st;
void main() {
    st=0;
    p=s;
    while (1) {
        c=*p;
        if (0==c) {
            switch (st) {
            case 1:printf("_\n");    break;
            case 2:printf("%s\n",p1);break;
            }
            break;//
        }
        switch (st) {
        case 0:
                 if ('_'==c) {                            st=0;}
            else if (','==c) {                            st=1;}
            else             {p1=p;                       st=2;}
        break;
        case 1:
                 if ('_'==c) {                            st=1;}
            else if (','==c) {printf("_\n");              st=1;}
            else             {p1=p;                       st=2;}
        break;
        case 2:
                 if ('_'==c) {*p=0;printf("%s\n",p1);*p=c;st=0;}
            else if (','==c) {*p=0;printf("%s\n",p1);*p=c;st=1;}
            else             {                            st=2;}
        break;
        }
        p++;
    }
}
//1
//22
//333
//_
//4444
//55555
//666666
提醒:正则表达式不是万能的;而有限状态自动机是万能的。
嗯,谢谢赵老师的指点。
_明月 2016-10-19
  • 打赏
  • 举报
回复
引用 3 楼 Forty2 的回复:
按说Regex支持反向引用,可以只用一趟替换。 static void Main() { string msg = "我...我我..我我我我....爱爱爱..爱..爱...你你...你..你你你..."; string pattern = @"(?<c>[^.])\.*(\k<c>\.*)*"; string result = Regex.Replace(msg, pattern, "${c}"); } 注释版:
static void Main()
{
    string msg = "我...我我..我我我我....爱爱爱..爱..爱...你你...你..你你你...";
    string pattern = 
        @"
            (?<c>           # 开启捕获组,名字叫c
                [^.]        #   匹配除'.'以外的任何一个字符
            )               # 结束捕获组
            \.*             # 任意个的'.'
            (               # 开启捕获组
                \k<c>       #   匹配上一个名字叫c的捕获组
                \.*         #   任意个的'.' 
            )*              # 结束捕获组,并允许该组任意重复
        ";
    string result = new Regex(pattern, RegexOptions.IgnorePatternWhitespace).Replace(msg, "${c}");
}
谢谢您的回复。 前辈对于正则表达式的研究很深入啊,你写的正则表达式有些地方我都看不懂。 我本帖中的问题,第二层的网友已经给出了答案。谢谢你们
赵4老师 2016-10-19
  • 打赏
  • 举报
回复
仅供参考:
//有字符串
//1_22_333,,4444__55555,_666666
//需要解析为
//1
//22
//333
//_
//4444
//55555
//666666
#include <stdio.h>
char s[]="1_22_333,,4444__55555,_666666";
char c,*p,*p1;
int st;
void main() {
    st=0;
    p=s;
    while (1) {
        c=*p;
        if (0==c) {
            switch (st) {
            case 1:printf("_\n");    break;
            case 2:printf("%s\n",p1);break;
            }
            break;//
        }
        switch (st) {
        case 0:
                 if ('_'==c) {                            st=0;}
            else if (','==c) {                            st=1;}
            else             {p1=p;                       st=2;}
        break;
        case 1:
                 if ('_'==c) {                            st=1;}
            else if (','==c) {printf("_\n");              st=1;}
            else             {p1=p;                       st=2;}
        break;
        case 2:
                 if ('_'==c) {*p=0;printf("%s\n",p1);*p=c;st=0;}
            else if (','==c) {*p=0;printf("%s\n",p1);*p=c;st=1;}
            else             {                            st=2;}
        break;
        }
        p++;
    }
}
//1
//22
//333
//_
//4444
//55555
//666666
提醒:正则表达式不是万能的;而有限状态自动机是万能的。
_明月 2016-10-19
  • 打赏
  • 举报
回复
引用 2 楼 stherix 的回复:
变量写错了
29行的msg应该为msg2


嗯,是的,错误就在这里。谢谢

我想知道,你是如何发现这个错误的?我当时就一直不明白是怎么回事!我仔细想了一想自己的解题思路,思路无误,代码也无“错误”。当时,就是不知道第29行的msg应该改成msg2 。 这个msg我当时考虑的是msg2,但是可能敲代码时,一下敲成了msg!








Forty2 2016-10-19
  • 打赏
  • 举报
回复
按说Regex支持反向引用,可以只用一趟替换。 static void Main() { string msg = "我...我我..我我我我....爱爱爱..爱..爱...你你...你..你你你..."; string pattern = @"(?<c>[^.])\.*(\k<c>\.*)*"; string result = Regex.Replace(msg, pattern, "${c}"); } 注释版:
static void Main()
{
    string msg = "我...我我..我我我我....爱爱爱..爱..爱...你你...你..你你你...";
    string pattern = 
        @"
            (?<c>           # 开启捕获组,名字叫c
                [^.]        #   匹配除'.'以外的任何一个字符
            )               # 结束捕获组
            \.*             # 任意个的'.'
            (               # 开启捕获组
                \k<c>       #   匹配上一个名字叫c的捕获组
                \.*         #   任意个的'.' 
            )*              # 结束捕获组,并允许该组任意重复
        ";
    string result = new Regex(pattern, RegexOptions.IgnorePatternWhitespace).Replace(msg, "${c}");
}
_明月 2016-10-18
  • 打赏
  • 举报
回复
本则帖子中引用的《江山与情 两首》,是金庸武侠小说《侠客行》中的一首古诗。 《侠客行》本部小说,在87、2001被翻拍成电视剧。2001年翻拍的电视剧有些不清晰,不过剧情还是挺丰富的。在剧中,各类武林人物交手搏斗场面不可胜数,但历历写来,景随情转,变化无穷而皆能贴合生活,让你如同身临其境。 希望能够得到各位前辈、小伙伴的指点,帮我解决本帖中遇到的问题。

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧