Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.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,试图想出一个“简单”的正则表达式来屏蔽看起来可能包含帐号的文本 用通俗易懂的英语: 任何包含一个数字或一列这样的单词的单词都应该匹配 保留最后4个数字不变 用四个X的xxxx替换匹配字符串的所有先前部分 到目前为止 我正在使用以下命令: [\-0-9 ]+(?<m1>[\-0-9]{4}) 但这遗漏了下面最后几个示例 样本数据: 实际结果 预期结果 这样的安排是否可以用正则表达式替换 我想我需要一些贪婪和前瞻性的功能,但我在这些方面没有经验。你试过这个吗: .*(?<m1&g

试图想出一个“简单”的正则表达式来屏蔽看起来可能包含帐号的文本

用通俗易懂的英语:

任何包含一个数字或一列这样的单词的单词都应该匹配 保留最后4个数字不变 用四个X的xxxx替换匹配字符串的所有先前部分 到目前为止

我正在使用以下命令:

[\-0-9 ]+(?<m1>[\-0-9]{4})
但这遗漏了下面最后几个示例

样本数据:

实际结果

预期结果

这样的安排是否可以用正则表达式替换

我想我需要一些贪婪和前瞻性的功能,但我在这些方面没有经验。

你试过这个吗:

.*(?<m1>[\d]{4})(?<m2>.*)
这就产生了

xxxx6789
xxxx5678
xxxx5678
xxxx3333
xxxx5678 test string

你不会让'a123b456'匹配。。。直到“b”变成一个数字-

以下是我的快速尝试:

(\s|^)([a-z]*\d+[a-z,0-9]+\s)+
这将选择所有这些测试用例。现在对于C代码,您需要检查每个匹配,以查看匹配序列的开头或结尾是否有空格,例如,最后一个示例将选择前后的空格

以下是执行替换的C代码:

var redacted = Regex.Replace(record, @"(\s|^)([a-z]*\d+[a-z,0-9]+\s)+",
    match => "xxxx" /*new String("x",match.Value.Length - 4)*/ + 
    match.Value.Substring(Math.Max(0, match.Value.Length - 4)));

这适用于您的示例:

var result = Regex.Replace(
    input,
    @"(?<!\b\w*\d\w*)(?<m1>\s?\b\w*\d\w*)+",
    m => "xxxx" + m.Value.Substring(Math.Max(0, m.Value.Length - 4)));
如果您的值像111 2233 33,它将打印xx3 33。如果您希望不包含空格,可以将lambda转换为多行语句,从值中删除空格


为了稍微解释一下regex模式,它有一个负的lookbehind,因此它确保后面的单词没有数字,数字周围有可选的单词字符。然后是m1部分,它查找包含数字的单词。在正则表达式模式解决了其余的问题后,最后四个字符通过一些C代码抓取。

我认为正则表达式不是解决这个问题的最佳方法,这就是为什么我要发布这个答案。对于如此复杂的情况,构建相应的正则表达式太困难,更糟糕的是,它的清晰度和适应性远远低于较长的代码方法

这些行下面的代码提供了您想要的确切功能,它足够清晰并且可以轻松扩展

string input = "this is a a1234 b5678 test string";
string output = "";
string[] temp = input.Trim().Split(' ');
bool previousNum = false;
string tempOutput = "";
foreach (string word in temp)
{
    if (word.ToCharArray().Where(x => char.IsDigit(x)).Count() > 0)
    {
        previousNum = true;
        tempOutput = tempOutput + word;
    }
    else
    {
        if (previousNum)
        {
            if (tempOutput.Length >= 4) tempOutput = "xxxx" + tempOutput.Substring(tempOutput.Length - 4, 4);
            output = output + " " + tempOutput;
            previousNum = false;
        }
        output = output + " " + word;
    }
}
if (previousNum)
{
    if (tempOutput.Length >= 4) tempOutput = "xxxx" + tempOutput.Substring(tempOutput.Length - 4, 4);
    output = output + " " + tempOutput;
    previousNum = false;
}

对不起,我看不出有什么问题?你得到的错误结果是什么?@Sniffer我已经根据他的模式添加了实际结果。你预期的结果正确吗?XXB456看起来不应该在那里。这将取代上一个例子中的a。在我写答案时,他的例子也删除了这个。此后,要求发生了变化-一个快速的评论,你说如果!previousNum previousNum=真;只需说previousNum=true,就可以降低复杂性;以及删除if语句。为此,它将圈复杂度降低1statement@joe_coolish你完全正确。我写代码很快。除此之外,+1用于打开正则表达式!我同意纯正则表达式不是最好的方法。。。但这就是我的梦想quest@BrianAdkins我很高兴看到我们都同意这一点。您可以继续尝试使用基于regex的方法,因为有人指示您这样做,或者因为这是一个个人挑战,或者因为任何原因,如果您没有找到任何能够提供足够准确的解决方案的方法,那么您可以依赖此代码。
xxxx6789
xxxx5678
xxxx5678
xxxx3333
xxxx5678 test string
(\s|^)([a-z]*\d+[a-z,0-9]+\s)+
var redacted = Regex.Replace(record, @"(\s|^)([a-z]*\d+[a-z,0-9]+\s)+",
    match => "xxxx" /*new String("x",match.Value.Length - 4)*/ + 
    match.Value.Substring(Math.Max(0, match.Value.Length - 4)));
var result = Regex.Replace(
    input,
    @"(?<!\b\w*\d\w*)(?<m1>\s?\b\w*\d\w*)+",
    m => "xxxx" + m.Value.Substring(Math.Max(0, m.Value.Length - 4)));
string input = "this is a a1234 b5678 test string";
string output = "";
string[] temp = input.Trim().Split(' ');
bool previousNum = false;
string tempOutput = "";
foreach (string word in temp)
{
    if (word.ToCharArray().Where(x => char.IsDigit(x)).Count() > 0)
    {
        previousNum = true;
        tempOutput = tempOutput + word;
    }
    else
    {
        if (previousNum)
        {
            if (tempOutput.Length >= 4) tempOutput = "xxxx" + tempOutput.Substring(tempOutput.Length - 4, 4);
            output = output + " " + tempOutput;
            previousNum = false;
        }
        output = output + " " + word;
    }
}
if (previousNum)
{
    if (tempOutput.Length >= 4) tempOutput = "xxxx" + tempOutput.Substring(tempOutput.Length - 4, 4);
    output = output + " " + tempOutput;
    previousNum = false;
}