搜索:匹配正则表达式时添加(带或不带空格)

时间:2014-11-21 09:24:34

标签: c# regex wpf search whitespace

我有一个静态方法,可以获得搜索的input string。在此方法中,它将此输入字符串拆分为空格,并在每个输入字符串上使用搜索算法(RavenQueryable)。此搜索输入可以包括(荷兰语)邮政编码,并且客户希望搜索所有这些邮政编码,关于是否有空格。

在半码中 - 我拥有的:

// Replace multiple whitespaces in the search-input for a single one
// Split the search-input at a single space
// Use RavenQueryable's SearchMultiple-method on this array of strings

我想用以下内容替换它:

// Replace multiple whitespaces in the search-input for a single one
// Find a (part of) a postcode regex with a whitespace "[1-9][0-9]{3}[ ][A-Za-z]{2}" or @"[\d][ ][A-Za-z]"
// var string with this postcode without spaces (replaced for "[1-9][0-9]{3}[A-Za-z]{2}" or @"[\d][A-Za-z]")
// Find a postcode regex without a whitespace "[1-9][0-9]{3}[A-Za-z]{2}" or @"[\d][A-Za-z]"
// var string with this postcode with a single whitespace (replaced for "[1-9][0-9]{3}[ ][A-Za-z]{2}" or @"[\d][ ][A-Za-z]")
// Split the search-input at a single space
// Use RavenQueryable's SearchMultiple-method on this array of strings

这种方式当用户输入邮政编码(有或没有空格并不重要)时,它会发现所有出现的事件(有或没有空格)

举个例子:

  • 当用户输入1234 AB时:它为1234AB和1234 AB的两个项目提供结果
  • 当用户输入1234AB时:它为1234AB和1234 AB的两个项目提供结果

我已经拥有的一些代码:

public static IRavenQueryable<T> SearchMultiple<T>(this IRavenQueryable<T> self,
    Expression<Func<T, object>> fieldSelector, string queries,
    decimal boost = 1, SearchOptions options = SearchOptions.Or)
{
    if(string.IsNullOrEmpty(queries) throw new ArgumentNullException("queries");

    queries = Regex.Replace(queries, @"\s{2,}", " ");
    // Postcode code
    var searchValues = queries.Split(' ');

    return self.SearchMultiple(fieldSelector, searchValues, boost, options);
}

那么,我如何制作这个// Postcode code所以我替换了我的#34;我所拥有的半代码&#34;对于我的&#34;我想用半代码替换它&#34;?


编辑:

  • 我知道如何获取邮政编码正则表达式:var postcode = Regex.Match(queries, "[1-9][0-9]{3}[A-Za-z]{2}");
  • 我只是不知道如何用另一个正则表达式替换正则表达式。我知道有一个Regex.Replace,但这会替换所选字符串的整个正则表达式。我想要的是替换匹配正则表达式的整个字符串,用于相同的字符串(但带有空格)。

如果我只接受整个邮政编码(如1234AB / 1234 AB),我会使用string-substring在第4个字符后添加/替换空格。但由于我还想让用户将部分邮政编码作为有效搜索(如34A / 34 A,也需要搜索1234AB和1234 AB),我不能使用子字符串在第4个角色之后。

我希望这能清除一些我想要达到的目标和我陷入困境的事情。是否有某种替换正则表达式用于正则表达式加上添加的字符(就像我的情况下的空格)方法,因为那样会很棒。


编辑2:

好的,我找到了a regex for regex replace method here,我只是不知道如何将它应用到我的案例中。

当我尝试以下代码时,它给出了一个ArgumentException,表明我的正则表达式是不正确的。我几乎从不使用正则表达式,也不太了解它,所以任何帮助都会受到赞赏。

if (string.IsNullOrEmpty(queries)) throw new ArgumentNullException("queries");

queries = Regex.Replace(queries, @"\s{2,}", " ");
const string withSpaceRegex = @"?<decimals>[\d][ ]?<letters>[A-Za-z]";
const string withoutSpaceRegex = @"?<decimals>[\d]?<letters>[A-Za-z]";
const string replacementWithSpace = "${decimals}${letters}";
const string replacementWithoutSpace = "${decimals} ${letters}";
var postcodesWithSpace = Regex.Matches(queries, withSpaceRegex);
var postcodesWithoutSpace = Regex.Matches(queries, withoutSpaceRegex);
queries = postcodesWithSpace.Cast<string>().Aggregate(queries, (current, s) => current
    + " " + Regex.Replace(s, s, replacementWithSpace, RegexOptions.IgnoreCase));
queries = postcodesWithoutSpace.Cast<string>().Aggregate(queries, (current, s) => current
    + " " + Regex.Replace(s, s, replacementWithoutSpace, RegexOptions.IgnoreCase));
var searchValues = queries.Split(' ');ostcodeWithoutSpace, RegexOptions.IgnoreCase));
var searchValues = queries.Split(' ');

return self.SearchMultiple(fieldSelector, searchValues, boost, options);

1 个答案:

答案 0 :(得分:0)

好的,我遇到的一些事情在下面做了这个半答案:

  • 由于我执行了.Split(' ');,我不需要评估已经有空格的那些,我只需要将没有空格的邮政编码添加到查询中作为完全相同的邮政编码(而是使用一个空间)。
  • 显然,您可以为您的正则表达式部分指定变量名称,而不是使用Regex.Replace

所以,现在我的方法中有以下代码,它修复了我的正则表达式替换问题:

if (string.IsNullOrEmpty(queries)) throw new ArgumentNullException("queries");

var newQueries = Regex.Replace(queries, @"\s{2,}", " ");
var withSpaceRegex = @"(?<decimals>[0-9]+)[ ](?<letters>[A-Za-z]+)";
var replacementWithSpace = "${decimals}${letters}";
var postcodesWithSpace = Regex.Matches(newQueries, withSpaceRegex);
newQueries = postcodesWithSpace.Cast<object>().Aggregate(newQueries, (current, s) => current
    + " " + Regex.Replace(s.ToString(), withSpaceRegex, replacementWithSpace, RegexOptions.IgnoreCase));
var searchValues = newQueries.Split(' ');

return self.SearchMultiple(fieldSelector, searchValues, boost, options);

一些例子:

  • &#34; 1234AB&#34; - &GT; &#34; 1234AB&#34;
  • &#34;有些话1234AB&#34; - &GT; &#34;一些单词1234AB&#34;
  • &#34; 1234 AB&#34; - &GT; &#34; 1234 AB 1234AB&#34;
  • &#34;有些字1234 AB&#34; - &GT; &#34;有些字1234 AB 1234AB&#34;

所以这确实修复了我的正则表达式。唯一的问题是我们对SearchOptions.And使用了RavenQueryable#SearchMultiple,所以现在它不再匹配了。

基本上,上面的代码修复了我的正则表达式替换问题,但现在我需要弄清楚如何将字符串数组的一部分用作SearcOptions.Or(包含和不包含空格的邮政编码),其余部分(包括这些邮政编码)为SearchOptions.And。然而,这是一个全新的问题,我将首先与我的一位同事讨论,该同事比我更了解Raven,如果他不知道解决方案,我和#39 ;提出一个新问题。


编辑:我们已经决定将所有带空格的邮政编码转换为相同的部分,而不是在我们导入所有内容和保存新内容时。所以我只是将上面的正则表达式应用到导入部分,之后只允许用户输入没有空格的邮政编码添加新的。