去掉非数字,然后在LINQ中得到字符串的最后n个字符
本文关键字:字符串 最后 字符 数字 然后 LINQ | 更新日期: 2023-09-27 18:09:28
我有两个表,它们都有一个Phone列。
这个列- nvarchar(30)-可以用几种不同的方式格式化其存储的数据,从0001 222333444到222 333444到(0001)-222333444到-,甚至是一个空字符串。
我想使用LINQ做一个查询,上面显示的前三个例子会给出一个匹配,所以我需要去掉所有不是数字的东西,然后从字符串中得到最后9个数字。但是,我不能只使用一个查询就做到这一点,而是循环遍历每个结果并在那里应用电话号码过滤器。有什么方法可以只用查询完成吗?
String
本质上是一个IEnumerable<char>
,所以你可以做的是:
var digits = s.Where(char.IsDigit);
现在,没有真正优雅的方法来取最后9位数字:IEnumerable<>
意味着没有办法找出它的长度,除了迭代它。我的建议是:
var digits = new string(s.Where(char.IsDigit).Reverse().Take(9).Reverse().ToArray());
或者你也可以自己编写TakeLast()
扩展方法:
public static IList<T> TakeLast<T>(this IEnumerable<T> enumerable, int n)
{
var queue = new Queue<T>(n);
foreach(var item in enumerable)
{
queue.Enqueue(item);
if(queue.Count > n)
queue.Dequeue();
}
return queue.ToList();
}
这将大大简化你的代码:
var digits = new string(s.Where(char.IsDigit).TakeLast(9).ToArray());
与Jonesopolis的回答类似,您可以执行以下操作来从字符串中获取最后N个字符:
var str = "0001 222 333 444";
var n = 9;
var result = string.Concat(str.Where(char.IsDigit).Skip(str.Length - n).Take(n));
将跳过前几个字符并拉回最后的n
字符数。您可能需要对字符串长度进行测试,以确保字符串包含足够的字符-我还没有测试过,所以如果字符串太短,它可能会抛出错误。
假设一个实体框架映射类:
public class Person
{
public int Id { get; set; }
public string Phone { get; set; }
}
和包含
的EF上下文public DbSet<Person> Persons
你可以使用像
这样的内容进行过滤var ppl = context.Persons.Where(x => x.Phone.Replace(" ", "").EndsWith("222333444")).ToList();
这将产生如下所示的SQL,满足您对过滤解决方案的请求。
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Phone] AS [Phone]
FROM [dbo].[People] AS [Extent1]
WHERE REPLACE([Extent1].[Phone], N' ', N'') LIKE N'%222333444'
那么任何格式都可以应用于中间层/模型生成器/自动生成器样式的解决方案。
如何将Regex &LINQ:
Regex r1 = new Regex("[^0-9.]");
Regex r2 = new Regex("(.{9})$");
var Last9Digits = PhoneNumbers.Select(PhoneNo => r2.Match(r1.Replace(PhoneNo, "")));
/// <summary>
/// Get the last N characters of a string.
/// </summary>
public static string GetLast(this string source, int numberOfChars)
{
if (string.IsNullOrEmpty(source) || numberOfChars >= source.Length)
return source;
return source.Substring(source.Length - numberOfChars);
}