除了最后n个字符外,将字符串的所有字符掩码化

20
我想知道如何替换字符串中的字符,但要满足“除了最后几个数字字符”的条件?
例如:
string = "4111111111111111";

我想要让它变成这样

new_string = "XXXXXXXXXXXXX1111"

在这个例子中,我将字符替换为“X”,除了最后4个字符以外。
我该如何实现这个目标?

1
你的意思是每次只取最后四个字符吗? - tariq
@tariq,它不是固定的。并非每次如此。 - cheol.lui
那么,确定要显示多少个字符取决于什么? - tariq
10个回答

31
var input = "4111111111111111";
var result = new String('X', input.Length - 4) + input.Substring(input.Length - 4);

Console.WriteLine(result);

// Ouput: XXXXXXXXXXXX1111

这个解决方案对我非常有效,而且简洁明了。谢谢! - Lexi847942

13

怎么样做个类似这样的东西...

new_string = new String('X', YourString.Length - 4)
                  + YourString.Substring(YourString.Length - 4);

根据当前字符串长度-4创建一个新的字符串,全部用“X”填充。然后添加原始字符串的最后4个字符。

1
这是我见过的最美妙的实现。太棒了。你用一行代码完成了我七行才能实现的功能。 - DotNetRussell

9
这里有一种思考方法。调用离 n 最后的数字字符:
  1. 将有多少个字符被 X 替换?字符串长度减去 n
  2. 如何用其他字符替换字符?不能直接修改 string,但可以构建一个新的字符串。
  3. 如何从原始字符串中获取最后的 n 个字符?有几种方法可以做到这一点,但最简单的可能是 Substring,它允许我们通过指定起点和可选的终点来抓取字符串的一部分。
因此,它可能看起来像这样(其中 n 是要从原始字符串中保留的字符数,str 是原始字符串 - string 不能是您的变量名称,因为它是一个保留关键字):
// 2. Start with a blank string
var new_string = "";

// 1. Replace first Length - n characters with X
for (var i = 0; i < str.Length - n; i++)
    new_string += "X";

// 3. Add in the last n characters from original string.
new_string += str.Substring(str.Length - n);

@cheol.lui,这对您可能有用,但是创建变量,循环以及常量字符串+一次一个字符和垃圾收集方面过度,确实有些浪费。是的,该描述很好地起到了给您提供“如何解决”的思维作用,但肯定不如其他发布的选项高效。 - DRapp

3

这可能有点过度,但这里提供了一个快速的扩展方法来实现这个功能。

默认使用x作为掩码字符,但可以用可选字符进行更改。

   public static class Masking
{
    public static string MaskAllButLast(this string input, int charsToDisplay, char maskingChar = 'x')
    {
        int charsToMask = input.Length - charsToDisplay;
        return charsToMask > 0 ? $"{new string(maskingChar, charsToMask)}{input.Substring(charsToMask)}" : input;
    }
}

这里是一些单元测试,以证明它的可行性。

 using Xunit;

    namespace Tests
{
    public class MaskingTest
    {
        [Theory]
        [InlineData("ThisIsATest", 4, 'x', "xxxxxxxTest")]
        [InlineData("Test", 4, null, "Test")]
        [InlineData("ThisIsATest", 4, '*', "*******Test")]
        [InlineData("Test", 16, 'x', "Test")]
        [InlineData("Test", 0, 'y', "yyyy")]
        public void Testing_Masking(string input, int charToDisplay, char maskingChar, string expected)
        {
            //Act
            string actual = input.MaskAllButLast(charToDisplay, maskingChar);

            //Assert
            Assert.Equal(expected, actual);
        }
    }
}

2
StringBuilder sb  = new StringBuilder();
Char[] stringChar = string.toCharArray();
for(int x = 0; x < stringChar.length-4; x++){
    sb.append(stringChar[x]);
}
sb.append(string.substring(string.length()-4));

string = sb.toString();

2

我猜你可以使用带有索引的 Select

string input = "4111111111111111";
string new_string = new string(input.Select((c, i) => i < input.Length - 4 ? 'X' : c).ToArray());

2

这里其他简洁的答案没有考虑字符串长度小于n的情况。以下是我的看法:

 var length = input.Length;                
 input = length > 4 ? new String('*', length - 4) + input.Substring(length - 4) : input;

1

lui,请尝试这个...

string dispString = DisplayString("4111111111111111", 4);

创建一个函数,传入原始字符串和数字数量。
    public string DisplayString(string strOriginal,int lastDigit)
    {
        string strResult = new String('X', strOriginal.Length - lastDigit) + strOriginal.Substring(strOriginal.Length - lastDigit);
        return strResult;
    }

也许可以帮助你....

0

试试这个:

String maskedString = "...."+ (testString.substring(testString.length() - 4, testString.length()));

0

虽然有点晚了,但我也想掩盖除最后 'x' 个字符以外的所有字符,但只掩盖数字或字母,以便任何 - ( )、其他格式等仍然显示。这是我的快速扩展方法,希望能帮助到某些人。我从Luke Hammer的示例开始,然后更改了内部实现以适应我的需求。

public static string MaskOnlyChars(this string input, int charsToDisplay, char maskingChar = 'x')
    {
        StringBuilder sbOutput = new StringBuilder();
        int intMaskCount = input.Length - charsToDisplay;

        if (intMaskCount > 0) //only mask if string is longer than requested unmasked chars
        {
            for (var intloop = 0; intloop < input.Length; intloop++)
            {
                char charCurr = Char.Parse(input.Substring(intloop, 1));
                byte[] charByte = Encoding.ASCII.GetBytes(charCurr.ToString());
                int intCurrAscii = charByte[0];

                if (intloop <= (intMaskCount - 1))
                {
                    switch (intCurrAscii)
                    {
                        case int n when (n >= 48 && n <= 57):
                            //0-9
                            sbOutput.Append(maskingChar);
                            break;

                        case int n when (n >= 65 && n <= 90):
                            //A-Z
                            sbOutput.Append(maskingChar);
                            break;

                        case int n when (n >= 97 && n <= 122):
                            //a-z
                            sbOutput.Append(maskingChar);
                            break;

                        default:
                            //Leave other characters unmasked
                            sbOutput.Append(charCurr);
                            break;
                    }
                }
                else
                {
                    //Characters at end to remain unmasked
                    sbOutput.Append(charCurr);
                }
            }
        }
        else
        {
            //if not enough characters to mask, show unaltered input
            return input;
        }
        return sbOutput.ToString();
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接