【问题标题】:String Replace in several combinations几种组合的字符串替换
【发布时间】:2014-09-28 06:43:18
【问题描述】:

我有一个带有 XY 坐标的文件,我想用数字“0”替换“空”坐标。

文件:

X123Y456
XY123
X123
Y123 
X123Y
XY123
X
Y

这样的模式:

X\n -> X0
Y\n -> Y0
XY  -> X0Y

实际上,我认为正则表达式会非常好用,但我不知道该怎么做。所以到目前为止我使用了简单的 String::Replace。对我来说复杂的事情是,不仅会发生情况,而且每行也不会只有一个。

我认为我应该能够做到:

System::Text::RegularExpressions::Regex::Replace(INPUT, PATTERN, REPLACE);

输入对我来说很清楚,由于不同的组,模式并不完全:

(^X$) -> X0
(Y$)  -> Y0
(^XY) -> X0Y
(^XY$) -> X0Y0

这会给出类似的东西。

(^X$)|(Y$)|(^XY)

替换将是 afaik 之类的:

$0 -> X0
$1 -> Y0
$2 -> X0Y

到目前为止我所做的只是简单的 String::Replace:

  void searchReplace(String^ sFile)
  {
    if(!System::IO::File::Exists(sFile))
      return;

    System::IO::StreamReader^ sr = gcnew System::IO::StreamReader(sFile);
    System::IO::StreamWriter^ sw = gcnew System::IO::StreamWriter(sFile + ".tmp");
    String^ newLine = System::Environment::NewLine;
    //System::Text::RegularExpressions::Regex regex = System::Text::RegularExpressions::Regex();
    String^ pattern = "(X"+newLine+")";
    String^ sLine = "";
    while((sLine = sr->ReadLine()) != nullptr)
    {
      String^ sRes = sLine->Trim()->Replace("Y"+newLine, "Y0");
      sRes = sRes->Replace("XY", "X0Y");
      sRes = sRes->Replace("X"+newLine, "X0"); 
      sw->WriteLine(sRes);
    }
    sr->Close();
    sw->Close();

    // TODO copy / delete

  }

由于其他问题尚未尝试此操作,但它基本上应该可以工作。但这对我来说似乎不是那么完美,正则表达式应该更好用。

有什么办法可以用正则表达式来做,还是用字符串替换最佳方式?如果是这样,我应该如何正确使用 Regex::Replace?

任何帮助/提示/建议都会非常好。


编辑解决方案:

感谢您的帮助。这是适合我的最终版本:

  void searchReplace(String^ sFile)
  {
    if(!System::IO::File::Exists(sFile))
      return;

    System::IO::StreamReader^ sr = gcnew System::IO::StreamReader(sFile);
    System::IO::StreamWriter^ sw = gcnew System::IO::StreamWriter(sFile + ".tmp");
    String^ sLine = "";
    while((sLine = sr->ReadLine()) != nullptr)
    {
      sw->WriteLine(Regex::Replace(sLine->Trim(), "(?<=[XY])(?=\D|$)(?!-)", "0"));
    }
    sr->Close();
    sw->Close();

    // TODO copy / delete

  }

输入:

X-123Y-456
XY-123
X123
Y123 
X123Y
XY123
X
Y

输出:

X-123Y-456
X0Y-123
X123
Y123
X123Y0
X0Y123
X0
Y0

编辑 2: 为我的描述中没有提到的负坐标添加了模式。

(?<=[XY])(?=\D|$)(?!-)

【问题讨论】:

  • 你真的想要XY -&gt; X0Y而不是XY -&gt; X0Y0吗?
  • 在“XY\n”的情况下应该将其替换为“X0Y0”,但在“XY123”的情况下不应该。所以这取决于替换的顺序。
  • 在这种情况下应该没问题,是的。

标签: c++ .net regex string replace


【解决方案1】:

您可以使用以下正则表达式:

String output = Regex.Replace(input, @"(?<=[XY])(?=\D|$)", "0");

解释

(?<=       # look behind to see if there is:
  [XY]     #   any character of: 'X', 'Y'
)          # end of look-behind
(?=        # look ahead to see if there is:
  \D       #   non-digits (all but 0-9)
 |         #  OR
  $        #   before an optional \n, and the end of the string
)          # end of look-ahead

(Live Demo|Working Demo)

【讨论】:

  • 很好,但它也应该捕获“XY123”和“X123Y”。从页面上看似乎没有?!我错了吗?
  • 因为在 XY123 中 X 是一个空坐标,我需要用 X0 替换它。基本上你可以说每个没有数字的坐标(X 或 Y)都应该被 X0 或 Y0 替换。不管位置在哪里
  • 看起来更好,我明天在我的代码中尝试一下。让你知道它是否对我有用
  • 它有效,需要我自己扩展负坐标。在我的帖子底部发布了我的解决方案。感谢您的帮助
  • 你能给我看一个应该或不应该被替换的负字符串的例子吗,我可能会让这个工作更好
【解决方案2】:

正则表达式

(X|Y)(?!\d)

匹配所有后面没有数字的“X”或“Y”实例,并捕获第一个捕获组中的哪一个(X 或 Y)。

你可以像这样使用它

output = System::Text::RegularExpressions::Regex.Replace(input, "(X|Y)(?!\\d)", "$10");

请注意,此表达式将“XY”替换为“X0Y0”,而不是“X0Y”。这可以接受吗?

【讨论】:

  • 如果 Y 不在行尾,则不应设置“X0Y0”。例如。它也可以是“XY123”,它将被 X0Y0 替换。
  • 当然,这会将“XY123”替换为“X0Y123”。只是字符串“XY”将被“X0Y0”替换,您的示例可能会被解释为“X0Y”将是正确的输出......
  • 我认为你的代码也可以工作,是的。感谢您的帮助。
猜你喜欢
  • 2013-01-28
  • 1970-01-01
  • 1970-01-01
  • 2016-08-22
  • 2011-02-10
  • 1970-01-01
  • 2012-04-26
  • 2020-08-18
  • 1970-01-01
相关资源
最近更新 更多