【问题标题】:Search: Add when matches regex (with or without space)搜索:匹配正则表达式时添加(带或不带空格)
【发布时间】:2014-11-21 09:24:34
【问题描述】:

我有一个静态方法可以获取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,以便我将“我拥有的半代码”替换为“我想用半代码替换它的内容”?


编辑:

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

如果我只接受整个邮政编码(如 1234AB / 1234 AB),我只会使用字符串子字符串在第 4 个字符后添加/替换空格。但是由于我还希望允许用户将部分邮政编码作为有效搜索(如 34A / 34 A,它们也需要搜索 1234AB 和 1234 AB),所以我不能在后面使用子字符串第 4 个字符。

我希望这可以清除一些我想要实现的目标以及我遇到的问题。是否有某种替换正则表达式的正则表达式加上添加字符(在我的情况下是空格)方法,因为那会很棒。


编辑 2:

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

当我尝试以下代码时,它会给出一个 ArgumentException,表明我的正则表达式不正确。我几乎从不使用 Regex,也不太了解它,因此我们将不胜感激。

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);

【问题讨论】:

  • 很高兴你展示了你已经拥有的东西,但问题是什么?
  • @khillang 已编辑。我想知道搜索带有和不带有空格的邮政编码的代码
  • 这不是一个真正的“请为我编写代码”类型的地方。看来您已经控制了伪代码,为什么不尝试将其写出来,然后在遇到真正的问题时再回来? ;)
  • @khillang 再次编辑。我知道如何获取邮政编码部分,只是不知道如何将其替换为对应部分(有空格到没有空格,反之亦然)。

标签: c# regex wpf search whitespace


【解决方案1】:

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

  • 由于我执行了.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);

一些例子:

  • “1234AB”->“1234AB”
  • “一些词 1234AB”->“一些词 1234AB”
  • “1234 AB”->“1234 AB 1234AB”
  • “一些词 1234 AB”->“一些词 1234 AB 1234AB”

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

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


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多