用值替换字符串中的字典键
Posted
技术标签:
【中文标题】用值替换字符串中的字典键【英文标题】:Replacing a dictionary key in a string with the value 【发布时间】:2022-01-15 20:04:18 【问题描述】:我目前正在尝试实现一个 changeAbbreviations 函数。我正在接收来自 .csv 的消息,这些消息被加载到名为 txtContent 的文本框中。示例消息如下所示:
“嘿,刚刚听到你的语音邮件,我是 ROFL,谢谢你的笑话”
我有一个字典,其中包含一个 textspeak 缩写列表及其延长值,我还从一个 .csv 中读取,其结构如下:
ROFL,笑着在地上打滚 大声笑,大声笑 AFK,远离键盘 BRB,马上回来 等等
我要实现的是,在按钮单击事件上,该函数将被调用,用拉长的值替换缩写并将新消息推送到名为 txtContentClean 的文本框
该函数将遍历字符串中的每个单词,如果单词与字典键之一匹配,它将用值替换它。
我不太确定如何进行,并希望有人能够向我展示如何正确实现这一点。到目前为止,我已经在下面复制了我的代码:
字典:
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
Dictionary<string, string> dictionary = File.ReadAllLines("textwords.csv").Select(x =>
x.Split(",", StringSplitOptions.RemoveEmptyEntries))
.ToDictionary(key => key.FirstOrDefault().Trim(),
value => value.Skip(1).FirstOrDefault().Trim());
更改缩写功能:
public void changeAbbreviations(string content, Dictionary<string, string> dictionary)
var abbreviations = new List<string>();
foreach (string word in content.Split(' '))
bool wordExists = dictionary.ContainsKey(word);
if (wordExists)
abbreviations.Add(word);
foreach (string word in abbreviations)
content.Replace(word, dictionary[word]);
txtContentClean.Text = content;
按钮事件:
private void btnFilter_Click(object sender, RoutedEventArgs e)
changeAbbreviations();
我希望我已经正确设置了这个问题,并感谢您的任何帮助:)
【问题讨论】:
您也必须发布 textwords.csv 的一部分,以便我们进行测试 你还需要content = content.Replace(word, dictionary[word];
,因为Replace
不修改原始字符串,它返回修改后的字符串。如果有很多替换项,我建议使用 StringBuilder 代替 content
作为字符串
是否需要考虑大小写变化,比如“rofl”?
【参考方案1】:
我建议使用正则表达式并匹配而不是Split
,这可以在我们有标点符号时帮助我们,例如
Call me ASAP!
正则表达式可以很好地提取"ASAP"
,我们可以从字典中将其替换为as soon as possible
;当Split
将返回"Call", "me", "ASAP!"
而我们遇到麻烦 与"ASAP!"
代码:
using System.Text.RegularExpressions;
...
//DONE:
// 1. ReadLines - we don't want premature materialization
// 2. Split(..2..) - no more then 2 items (in case text has commas)
private m_Dictionary = File
.ReadLines("textwords.csv")
.Select(x => x.Split(",", 2, StringSplitOptions.RemoveEmptyEntries | ))
.Where(pair => pair.Length == 2)
.ToDictionary(pair => pair[0], pair => pair[1]);
//DONE: business logic only, no UI
public string changeAbbreviations(string content,
IDictionary<string, string> dictionary = null)
dictionary = dictionary ?? m_Dictionary;
if (string.IsNullOrEmpty(content))
return content;
// We try to change all uppercase words like ASAP, LOL etc.
return Regex.Replace(content, @"\b\pLu+\b", match =>
dictionary.TryGetValue(match.Value, out var text)
? text
: match.Value);
// UI only
private void btnFilter_Click(object sender, RoutedEventArgs e)
txtContentClean.Text = changeAbbreviations(txtContentClean.Text);
编辑:如果我们允许 digits 包含在缩写中,例如 "P2P", "I18N"
、"M8"
,则模式可以是
\b(?:\pLu+[0-9]*)+\b
即
...
return Regex.Replace(content, @"\b(?:\pLu+[0-9]*)+\b", match =>
dictionary.TryGetValue(match.Value, out var text)
? text
: match.Value);
...
【讨论】:
如果我想修改它以包含 L8R、Later 或 M8 等缩写词,Mate 是否需要对正则表达式进行大量调整? @Paddington:如果缩写必须从字母开始并且可以包含数字(例如P2P
、I18N
、K8S
、M8
) 正则表达式可以是(\pLu+[0-9]*)+
或\b(\pLu+[0-9]*)+\b
,如果缩写应该是一个单词
啊,我明白了,我还在掌握正则表达式语法 tysm!【参考方案2】:
试试这个
string content="LOL you are funny";
content = ChangeAbbreviations(content,dictionary);
结果
Laughing out loud you are funny
代码
public string ChangeAbbreviations(string content, Dictionary<string, string> dictionary)
string pattern =@"[^0-9a-zA-Z:,]+";
string[] strArray = Regex.Split(content, pattern,
RegexOptions.IgnoreCase,
TimeSpan.FromMilliseconds(500));
for (var i=0; i < strArray.Length; i++)
if ( dictionary.TryGetValue(strArray[i], out var wordFull))
strArray[i] = wordFull;
return string.Join(" ", strArray);
【讨论】:
以上是关于用值替换字符串中的字典键的主要内容,如果未能解决你的问题,请参考以下文章