一、适用场景
在客户管理、市场营销等领域,经常需要对收集到的手机号码进行去重处理,避免重复营销和数据冗余。这个 WPF 应用程序可以帮助用户快速对比两组手机号码数据,找出重复和不重复的号码,提高数据处理效率。
二、界面设计
- 主窗口包含四个文本框,分别用于显示原始数据、重复号码和不重复号码。
- 提供文件选择按钮,允许用户选择要对比的两个文本文件。
- 包含 "对比" 按钮用于执行对比操作,以及 "复制结果" 和 "导出结果" 按钮用于保存处理结果。
- 设计简洁明了,具有良好的视觉层次感和用户体验。
三、逻辑规则及详细代码步骤
下面是基于 WPF 的手机号码去重应用程序的完整实现:
<Application x:Class="PhoneNumberDeduplication.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
using System.Windows;
namespace PhoneNumberDeduplication
{
public partial class App : Application
{
}
}
<Window x:Class="PhoneNumberDeduplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="手机号码去重工具" Height="600" Width="800"
WindowStartupLocation="CenterScreen">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 文件选择区域 -->
<GroupBox Header="文件选择" Grid.Row="0" Grid.ColumnSpan="2" Margin="0,0,0,10">
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Content="文件1:" Grid.Column=0" VerticalAlignment="Center"/>
<TextBox x:Name="FilePath1" Grid.Column="1" Margin="5,0" IsReadOnly="True"/>
<Button x:Name="BrowseFile1" Content="浏览..." Grid.Column="2" Margin="5,0" Click="BrowseFile1_Click"/>
<Label Content="文件2:" Grid.Column="3" VerticalAlignment="Center"/>
<TextBox x:Name="FilePath2" Grid.Column="4" Margin="5,0" IsReadOnly="True"/>
<Button x:Name="BrowseFile2" Content="浏览..." Grid.Column="5" Margin="5,0" Click="BrowseFile2_Click"/>
</Grid>
</GroupBox>
<!-- 操作按钮 -->
<Button x:Name="CompareButton" Content="对比" Grid.Row="1" Grid.Column="0" Margin="0,0,5,10"
Height="30" FontWeight="Bold" Click="CompareButton_Click"/>
<Button x:Name="CopyButton" Content="复制结果" Grid.Row="1" Grid.Column="1" Margin="5,0,0,10"
Height="30" Click="CopyButton_Click" IsEnabled="False"/>
<Button x:Name="ExportButton" Content="导出结果" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"
Margin="0,0,0,10" Height="30" Click="ExportButton_Click" IsEnabled="False"/>
<!-- 结果显示区域 -->
<GroupBox Header="文件1内容" Grid.Row="3" Grid.Column="0" Margin="0,0,5,0">
<TextBox x:Name="FileContent1" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
TextWrapping="Wrap" IsReadOnly="True" Margin="5"/>
</GroupBox>
<GroupBox Header="文件2内容" Grid.Row="3" Grid.Column="1" Margin="5,0,0,0">
<TextBox x:Name="FileContent2" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
TextWrapping="Wrap" IsReadOnly="True" Margin="5"/>
</GroupBox>
<GroupBox Header="重复的手机号码" Grid.Row="4" Grid.Column="0" Margin="0,5,5,0">
<TextBox x:Name="DuplicateNumbers" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
TextWrapping="Wrap" IsReadOnly="True" Margin="5"/>
</GroupBox>
<GroupBox Header="不重复的手机号码" Grid.Row="4" Grid.Column="1" Margin="5,5,0,0">
<TextBox x:Name="UniqueNumbers" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
TextWrapping="Wrap" IsReadOnly="True" Margin="5"/>
</GroupBox>
<!-- 状态栏 -->
<StatusBar Grid.Row="5" Grid.ColumnSpan="2" Margin="0,5,0,0">
<StatusBarItem x:Name="StatusMessage">准备就绪</StatusBarItem>
</StatusBar>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using Microsoft.Win32;
namespace PhoneNumberDeduplication
{
public partial class MainWindow : Window
{
private List<string> _phoneNumbers1 = new List<string>();
private List<string> _phoneNumbers2 = new List<string>();
private List<string> _duplicateNumbers = new List<string>();
private List<string> _uniqueNumbers = new List<string>();
public MainWindow()
{
InitializeComponent();
}
private void BrowseFile1_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog
{
Filter = "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*",
Title = "选择第一个文本文件"
};
if (openFileDialog.ShowDialog() == true)
{
FilePath1.Text = openFileDialog.FileName;
ReadPhoneNumbersFromFile(openFileDialog.FileName, ref _phoneNumbers1, FileContent1);
}
}
private void BrowseFile2_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog
{
Filter = "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*",
Title = "选择第二个文本文件"
};
if (openFileDialog.ShowDialog() == true)
{
FilePath2.Text = openFileDialog.FileName;
ReadPhoneNumbersFromFile(openFileDialog.FileName, ref _phoneNumbers2, FileContent2);
}
}
private void ReadPhoneNumbersFromFile(string filePath, ref List<string> phoneNumbers, TextBox textBox)
{
try
{
StatusMessage.Content = $"正在读取文件: {filePath}";
// 清空现有数据
phoneNumbers.Clear();
textBox.Clear();
// 读取文件内容
string content = File.ReadAllText(filePath);
// 使用正则表达式提取手机号码
Regex regex = new Regex(@"1[3-9]\d{9}");
MatchCollection matches = regex.Matches(content);
// 提取不重复的手机号码
phoneNumbers = matches.Cast<Match>().Select(m => m.Value).Distinct().ToList();
// 显示文件内容
textBox.Text = string.Join(Environment.NewLine, phoneNumbers);
StatusMessage.Content = $"成功读取 {phoneNumbers.Count} 个手机号码";
}
catch (Exception ex)
{
MessageBox.Show($"读取文件时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
StatusMessage.Content = "读取文件时出错";
}
}
private void CompareButton_Click(object sender, RoutedEventArgs e)
{
try
{
if (_phoneNumbers1.Count == 0 || _phoneNumbers2.Count == 0)
{
MessageBox.Show("请先选择并读取两个文件的内容", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
StatusMessage.Content = "正在对比手机号码...";
// 找出重复的手机号码
_duplicateNumbers = _phoneNumbers1.Intersect(_phoneNumbers2).ToList();
// 找出不重复的手机号码
_uniqueNumbers = _phoneNumbers1.Except(_phoneNumbers2).Concat(_phoneNumbers2.Except(_phoneNumbers1)).ToList();
// 显示结果
DuplicateNumbers.Text = string.Join(Environment.NewLine, _duplicateNumbers);
UniqueNumbers.Text = string.Join(Environment.NewLine, _uniqueNumbers);
StatusMessage.Content = $"对比完成: 重复号码 {_duplicateNumbers.Count} 个, 不重复号码 {_uniqueNumbers.Count} 个";
// 启用复制和导出按钮
CopyButton.IsEnabled = true;
ExportButton.IsEnabled = true;
}
catch (Exception ex)
{
MessageBox.Show($"对比过程中出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
StatusMessage.Content = "对比过程中出错";
}
}
private void CopyButton_Click(object sender, RoutedEventArgs e)
{
try
{
string result = $"重复的手机号码 ({_duplicateNumbers.Count}):\n{string.Join(Environment.NewLine, _duplicateNumbers)}\n\n" +
$"不重复的手机号码 ({_uniqueNumbers.Count}):\n{string.Join(Environment.NewLine, _uniqueNumbers)}";
Clipboard.SetText(result);
StatusMessage.Content = "结果已复制到剪贴板";
}
catch (Exception ex)
{
MessageBox.Show($"复制结果时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
StatusMessage.Content = "复制结果时出错";
}
}
private void ExportButton_Click(object sender, RoutedEventArgs e)
{
try
{
SaveFileDialog saveFileDialog = new SaveFileDialog
{
Filter = "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*",
Title = "保存结果文件",
FileName = "手机号码对比结果_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".txt"
};
if (saveFileDialog.ShowDialog() == true)
{
string result = $"重复的手机号码 ({_duplicateNumbers.Count}):\n{string.Join(Environment.NewLine, _duplicateNumbers)}\n\n" +
$"不重复的手机号码 ({_uniqueNumbers.Count}):\n{string.Join(Environment.NewLine, _uniqueNumbers)}";
File.WriteAllText(saveFileDialog.FileName, result);
StatusMessage.Content = $"结果已导出到: {saveFileDialog.FileName}";
}
}
catch (Exception ex)
{
MessageBox.Show($"导出结果时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
StatusMessage.Content = "导出结果时出错";
}
}
}
}
四、代码说明
- 界面设计:使用 WPF 的 XAML 创建了一个包含文件选择、结果显示和操作按钮的窗口界面。
- 文件读取:通过 OpenFileDialog 选择文本文件,并使用正则表达式提取手机号码。
- 号码处理:使用 LINQ 的 Intersect 和 Except 方法找出重复和不重复的手机号码。
- 结果展示:将处理结果显示在相应的文本框中,并提供复制和导出功能。
- 异常处理:在文件操作和数据处理过程中添加了异常处理,确保程序的健壮性。
五、总结优化
这个 WPF 应用程序提供了一个简单而有效的解决方案来处理手机号码去重问题。不过,还有一些可以优化的地方:
- 性能优化:对于非常大的文件,可以考虑使用流式处理而不是一次性加载整个文件。
- 用户体验:可以添加进度条来显示处理大型文件时的进度。
- 功能扩展:可以添加更多的号码验证规则,支持不同格式的手机号码。
- 数据可视化:可以添加统计图表来直观展示重复和不重复号码的比例。
- 批量处理:可以扩展功能以支持多个文件的批量处理。
这个应用程序可以帮助用户快速有效地处理手机号码去重问题,提高工作效率,减少手动处理的错误。