Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 一步找到解决正则表达式的模式_C#_Regex - Fatal编程技术网

C# 一步找到解决正则表达式的模式

C# 一步找到解决正则表达式的模式,c#,regex,C#,Regex,我有一个问题,找到一个模式,解决问题的一步。 字符串如下所示: Text1 Text1$Text2$Text3 Text1$Text2$Text3$Text4$Text5$Text6 etc. 我想要得到的是:最多4倍的文本。如果有多个“4xText”,只取最后一个符号 例如: Text1$Text2$Text3$Text4$Text5$Text6 -> Text1$Text2$Text3$Text4&56 我目前的解决办法是: 第一种模式: ^([^\$]*)\$?([^\$

我有一个问题,找到一个模式,解决问题的一步。 字符串如下所示:

Text1
Text1$Text2$Text3
Text1$Text2$Text3$Text4$Text5$Text6 etc.
我想要得到的是:最多4倍的文本。如果有多个“4xText”,只取最后一个符号

例如:

Text1$Text2$Text3$Text4$Text5$Text6 -> Text1$Text2$Text3$Text4&56
我目前的解决办法是:

第一种模式:

^([^\$]*)\$?([^\$]*)\$?([^\$]*)\$?([^\$]*)\$?
在此之后,我将用第一个模式进行替换 新字符串:
Text5$Text6

第二种模式是:

([^\$])\b
结果:56

将两者结合起来,得到以下结果:

Text1$Text2$Text3$Text4$56

对我来说,不清楚为什么我不能轻易地把第一个模式之后的第二个模式变成一个模式。是否有类似于锚的东西,告诉引擎从这里启动模式,就像它在唯一的模式是Is时所做的那样?

您可以使用一个具有正向查找的替换,然后连接匹配项

(?<=^(?:[^$]+\$){0,3})[^$]+\$?|[^$](?=\$|$)
输出

Text1
Text1$Text2$Text3
Text1$Text2$Text3$Text4$56

我坚信正则表达式不是实现这一点的方法。主要是因为可读性

你可以考虑使用像这样的简单算法来达到你的目标:

using System;

public class Program
{
    public static void Main()
    {
        var input = "Text1$Text2$Text3$Text4$Text5$Text6";
        var parts = input.Split('$');
        
        var result = "";
        for(var i=0; i<parts.Length; i++){
            result += (i <= 4 ? parts[i] + "$" : parts[i].Substring(4));            
        }
        Console.WriteLine(result);
    }
}

它必须根据实际需要进行调整,但想法是存在的

我不清楚是否可以使用专门的正则表达式来实现您的目标。如果没有其他问题,那么您想要在输出中引入一个新字符
“&”
,这就增加了挑战,因为仅仅简单的匹配永远无法实现这一点。是否可能使用
Replace()
方法?但是我不确定这是否有效…仅使用替换模式而不是
匹配计算器
,我看不到识别的方法,但仍然将
“$Text”
部分从第五个实例和更高版本中排除

但是,如果您愿意将正则表达式与少量后处理混合使用,您肯定可以做到:

static readonly Regex regex1=new Regex(@“(Text\d(?:\$Text\d){0,3})(?:\$Text(\d))*”,RegexOptions.Compiled);
静态void Main(字符串[]参数)
{
(int i=1;i$“Text{j}”);
写线(保留四个(文本));
}
}
私有静态字符串KeepFour(字符串文本)
{
Match=regex1.Match(文本);
如果(!match.Success)
{
返回“[不匹配]”;
}
StringBuilder结果=新建StringBuilder();
result.Append(match.Groups[1].Value);
if(match.Groups[2].Captures.Count>0)
{
结果。追加(&);
//必须迭代(加入),因为我们不想要整个匹配,
//只是捕获的文本。
追加(JoinCaptures(match.Groups[2]);
}
返回result.ToString();
}
私有静态字符串JoinCaptures(组)
{
返回string.Join(“,group.Captures.Cast().Select(c=>c.Value));
}
上面将您的需求在正则表达式中分成三个不同的捕获组。然后它提取捕获的文本,并根据结果合成结果。

尝试以下代码:

var texts = new string[] {"Text1", "Text1$Text2$Text3", "Text1$Text2$Text3$Text4$Text5$Text6" };

var parsed = texts
     .Select(s => Regex.Replace(s, 
         @"(Text\d{1,3}(?:\$Text\d{1,3}){0,3})((?:\$Text\d{1,3})*)", 
         (match) => match.Groups[1].Value +"$"+ match.Groups[2].Value.Replace("Text", "").Replace("$", "")
     )).ToArray();

// parsed is now: string[3] { "Text1$", "Text1$Text2$Text3$", "Text1$Text2$Text3$Text4$56" }
说明:

解决方案使用正则表达式模式:
(Text\d{1,3}(?:\$Text\d{1,3}){0,3})((?:\$Text\d{1,3})*)

(…)
-第一个捕获组

(?:…)
-非捕获组

Text\d{1,3}(?:\$Text\d{1,3}
-按字面意思匹配
Text
,然后按字面意思匹配
\d{1,3}
,即1到3位数字,
\$
按字面意思匹配
$

其余的只是重复。基本上,第一组捕获前四个片段,第二组捕获其余的片段(如果有的话)

这里我们还使用
MatchEvaluator
,它是一种委托类型,定义为:

public delegate string MatchEvaluator(Match match);
我们定义这种方法:

(match) => match.Groups[1].Value +"$"+ match.Groups[2].Value.Replace("Text", "").Replace("$", "")

我们使用它来计算匹配,所以首先捕获组,然后与第二个组连接,删除不必要的文本。

亲爱的Abra,我使用C#正则表达式只允许选择连续文本。您的宿主语言可能提供一种通过捕获括号等方式提取子字符串的方法。regex真的是一种要求吗?有很多简单的方法好的,谢谢,所以我的解决方案没有错吗?不需要正则表达式。但是我喜欢它。你更喜欢什么?使用C#,我会对美元进行简单的分割,然后先取4,然后取剩余的。。。
public delegate string MatchEvaluator(Match match);
(match) => match.Groups[1].Value +"$"+ match.Groups[2].Value.Replace("Text", "").Replace("$", "")