【问题标题】:Find pipe in quotes ignore false positives [duplicate]在引号中查找管道忽略误报[重复]
【发布时间】:2019-07-02 15:00:38
【问题描述】:

我正在尝试用空格替换引号内的管道分隔字符。问题是我得到了很多误报,因为有些字符串是空的。如果引号之间有文本,我只想替换管道。我使用的正则表达式模式来自另一个 stackoverflow 帖子,因为我缺乏正则表达式技能。

数据样本:

"Hello"|"Green | Blue"|123.45|""|""|""|5|45

代码我正在使用:

internal class Program
{
    public static void Main()
    {
        string pattern = @"(?: (?<= "")|\G(?!^))(\s*[^"" |\s]+(?:\s +[^ 
        ""|\s]+)*)\s*\|\s*(?=[^""] * "")";
        string substitution = @"\1 \2";
        string input = @"""20190430|""Test  Text""|""""|""""|""Manual""|""""|""Machine""|""""|""""|10.00|""""|0.00|||0.00||5600.00||||""A+""|""""|40.00||""""|""Vision Service |Troubleshoot""|57|""Y""|838|""Yellow Maroon""|850||""FL""||||0.00|||||||||||""""||""""||""""|||""""||||||""""||""""|""""||""""|""""||||||""""|""""|""""||||||||1||""";
        RegexOptions options = RegexOptions.Multiline;
        Regex regex = new Regex(pattern, options);
        string result = regex.Replace(input, substitution);
        Console.WriteLine("Result:" + result);
        Console.ReadKey();
    }
}

它可以很好地替换“蓝绿色”管道。但它也会替换引号之间的管道,这会在列被删除时破坏文件。

使用我正在处理的文件的实际示例更新了代码。正则表达式找到它但不替换管道。缺少一些东西。

【问题讨论】:

  • 这与替换双引号外的逗号相同的解决方案。请参阅:stackoverflow.com/questions/3147836/…
  • 还要明确一点,最终输出应如下所示:"Hello"|"Green Blue"|123.45|""|""|""|5|45

标签: c# regex


【解决方案1】:

如果双引号之间应该有文本并且文本应该在管道的两侧,您可以使用:

(?<=")(\s*[^"\s|]+)\s*\|\s*([^\s"|]+\s*)(?=")

在替换中使用$1 $2

说明

  • (?&lt;=") 正向向后看,断言左边是"
  • (\s*[^"\s|]+) 在第 1 组中捕获匹配 0+ 次空白字符,1+ 次不匹配 "| 或空白字符
  • \s*\|\s* 匹配 | 在 0+ 倍之间的空白字符
  • ([^\s"|]+\s*) 在第 2 组中捕获匹配 1+ 次而不是 "| 或空白字符并匹配 0+ 次空白字符
  • (?=") 正向前瞻,断言右边是"

.NET Regex demo

编辑

如果您想用双引号之间的空格替换多个管道,您可以使用\G 锚来断言上一个匹配结束时的位置。

在替换中使用第一个捕获组,后跟空格$1

(?:(?<=")|\G(?!^))(\s*[^"|\s]+(?:\s+[^"|\s]+)*)\s*\|\s*(?=[^"]*")

说明

  • (?:非捕获组
    • (?&lt;=") 断言左边是"
    • |或者
    • \G(?!^)在上一场比赛结束时断言位置
  • )关闭非捕获组
  • (捕获组1
    • \s*[^"|\s]+ 匹配 0+ 次空白字符,然后匹配 1+ 次而不是 | 或空白字符
    • (?:\s+[^"|\s]+)* 重复 0+ 次匹配 1+ 个空白字符,后跟 1+ 次不是 | 或空白字符
  • )关闭捕获组1
  • \s*\|\s* 匹配 | 在 0+ 次之间的空白字符
  • (?=[^"]*") 断言右边是"

查看另一个.NET regex demo

【讨论】:

  • 此记录不匹配:""|"Vision Service |Assistant"|57|"Y"|838|0 或多个管道:"x390|Gigabyte|Awesome"|$249.00|" RGB"|""|""|""|0
  • @JayWehner 我已经为我的答案添加了更新。
  • 效果很好!你是正则表达式的真正向导!
  • 好吧,我总是说正则表达式看起来可以工作,但我的代码却不行。
  • 一切都好...该死的 IDE 正在向正则表达式添加空格!
【解决方案2】:

我的猜测是,我们可能还想在文本中只保留一个空格,而这个表达式,

"([^"]+?)\s+\|\s+([^"]+?)"

替换 $1 $2 可能会起作用。

Demo

示例

using System;
using System.Text.RegularExpressions;

public class Example
{
    public static void Main()
    {
        string pattern = @"""([^""]+?)\s+\|\s+([^""]+?)""";
        string substitution = @"\1 \2";
        string input = @"""Hello""|""Green | Blue""|123.45|""""|""""|""""|5|45";
        RegexOptions options = RegexOptions.Multiline;
        
        Regex regex = new Regex(pattern, options);
        string result = regex.Replace(input, substitution);
    }
}

【讨论】:

  • 经过进一步测试,这也不起作用。文本可以是任何东西。不仅仅是整个单词。所以这是一个可接受的字段:"x390|Gigabyte|Awesome"|$249.00|"RGB"|""|""|""|0
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 2015-03-11
  • 1970-01-01
  • 2015-08-06
  • 2017-10-21
相关资源
最近更新 更多