我正在尝试使用以下代码将1234567890123456
替换为************3456
:
Regex.Replace(xml,@"\b\d{13,16}\b", string.Concat(new String('*',12),a.Value.Substring(a.Value.Length - 4)));
a.Value
是数字,但只是结果:
****************
完整代码:
//Check if value is the credit card
if(a.Value.Length >= 13 && a.Value.Length <= 16)
xml = Regex.Replace(xml,@"\b\d{12}(?=\d{4})\b", new String('*',12));
else //If value is not a credit card, replace it with ***
xml = Regex.Replace(xml,@"\b\d+\b", "***");
我将if语句的第一部分替换为:
Regex.Replace(xml, @"\b\d{13,16}\b", match =>
String.Concat(new String('*', match.Length - 4), match.Value.Substring(match.Length - 4)));
但我仍然得到***
卡片。
这是XML。请注意,卡号可以在13到16位之间,我总是希望保留最后4位。
<Details>
<CreditCard cardnum='1234567890123456'
ccv='123'
exp='0212'
cardType='1'
name='joe' />
</Details>
长数字;
string xml = @"<Details>
<CreditCard cardnum='1234567890123456'
ccv='123'
exp='0212'
cardType='1'
name='joe' />
</Details>";
XElement element = XElement.Parse(xml);
IEnumerable<XElement> elementsWithPossibleCCNumbers =
element.Descendants()
.Where(d => d.Attributes()
.Where(a => a.Value.Length >= 13 && a.Value.Length <= 16)
.Where(a => long.TryParse(a.Value, out numeric))
.Count() == 1).Select(x=>x);
foreach(var x in elementsWithPossibleCCNumbers)
{
foreach(var a in x.Attributes())
{
//Check if the value is a number
if(long.TryParse(a.Value,out numeric))
{
//Check if value is the credit card
if(a.Value.Length >= 13 && a.Value.Length <= 16)
Regex.Replace(xml,@"\b\d{12}(?=\d{4}\b)", new String('*',12));
else //If value is not a credit card, replace it with ***
xml = Regex.Replace(xml,@"\b\d+\b", "***");
}
}
}
答案 0 :(得分:3)
您可以使用前瞻来匹配尾随的4位数,但保留它们:
Regex.Replace(xml,@"\b\d{12}(?=\d{4}\b)", new String('*',12))
修改:此版本更接近您的代码。但是,它不是依赖于预先设置的a.Value
,而是使用match
变量来允许您对正则表达式中实际捕获的内容应用转换。
Regex.Replace(xml, @"\b\d{13,16}\b", match =>
new String('*', match.Length - 4) +
match.Value.Substring(match.Length - 4));
上面的代码假定您希望编辑的字符串与原始字符串具有相同的长度,并保留最后4位数字。
如果要编辑前12位数并保留剩余的数字(1-4位数),请使用:
Regex.Replace(xml, @"\b\d{13,16}\b", match =>
new String('*', 12) +
match.Value.Substring(12));
修改:我想你已经知道了。但是你需要做的就是替换:
xml = Regex.Replace(xml, …
使用:
a.Value = Regex.Replace(a.Value, …
编辑:我完成了您现在完成的代码,我意识到您甚至不需要正则表达式来完成您要完成的任务,因为您要替换属性值整体。以下是我将如何调整您的代码(通过一些更改):
string xml = @"
<Details>
<CreditCard cardnum='1234567890123456'
ccv='123'
exp='0212'
cardType='1'
name='joe' />
</Details>";
XElement element = XElement.Parse(xml);
IEnumerable<XElement> elementsWithPossibleCCNumbers =
element.Descendants()
.Where(d => d.Attributes()
.Select(a => a.Value)
.Any(v => v.Length >= 13 &&
v.Length <= 16 &&
v.All(Char.IsDigit)));
foreach (var x in elementsWithPossibleCCNumbers)
{
foreach (var a in x.Attributes())
{
//Check if the value is a number
if (a.Value.All(Char.IsDigit))
{
//Check if value is the credit card
if (a.Value.Length >= 13 && a.Value.Length <= 16)
a.Value = new String('*', a.Value.Length - 4) + a.Value.Substring(a.Value.Length - 4);
else //If value is not a credit card, replace it with ***
a.Value = "***";
}
}
}
xml = element.ToString();
答案 1 :(得分:0)
您可以使用MatchEvaluator,在这种情况下,我使用了lambda。
[Test]
public void Test()
{
string xml = "foo 1234567890123456 bar";
Debug.WriteLine(Regex.Replace(xml, @"\b\d{9,12}(?=\d{4}\b)", m => new string('*', m.Value.Length)));
}
foo ************3456 bar