如何在控制台應用程序的 Console.WriteLine 中為不同顏色的單詞著色? (How to color words in different colours in a Console.WriteLine in a console application?)


問題描述

如何在控制台應用程序的 Console.WriteLine 中為不同顏色的單詞著色? (How to color words in different colours in a Console.WriteLine in a console application?)

我的代碼的最後一句是一個帶有變量的Console.WriteLine。我想讓 "" 之間的文本為綠色,變量為紅色。

我一直在嘗試使用 Console.Foregroundcolor,但這並不成功。

Console.WriteLine("What is your name?");
string name = Console.ReadLine();
Console.WriteLine("Your name is {0}.", name);
Console.ReadKey();

參考解法

方法 1:

An slight improvement on currarpickt's answer:

public void Write(params object[] oo)
{
  foreach(var o in oo)
    if(o == null)
      Console.ResetColor();
    else if(o is ConsoleColor)
      Console.ForegroundColor = o as ConsoleColor;
    else
      Console.Write(o.ToString());
}

Now you can mix any number of text and color:

 Write("how about ", ConsoleColor.Red, "red", null, " text or how about ", ConsoleColor.Green, "green", null, " text");

Using null puts the color back to default

Or how about we build a parser:

public void Write(string msg)
{
  string[] ss = msg.Split('{','}');
  ConsoleColor c;
  foreach(var s in ss)
    if(s.StartsWith("/"))
      Console.ResetColor();
    else if(s.StartsWith("=") && Enum.TryParse(s.Substring(1), out c))
      Console.ForegroundColor = c;
    else
      Console.Write(s);
}

And we can use like:

Write("how about {=Red}this in red{/} or this in {=Green}green{/} eh?");

Should tidy things up. It's a really simple unsophisticated parser though, you'll need to improve it if your strings contain { or } for example

方法 2:

I liked Caius Jard's parser answer, but I improved upon it a little bit so you can change both the background color and the foreground color, and even nest colors. I've created a new static class called ConsoleWriter.

To set foreground color:

ConsoleWriter.WriteLine("{FC=Red}This text will be red.{/FC}");

To set background color:

ConsoleWriter.WriteLine("{BC=Blue}This background will be blue.{/BC}");

It even keeps track of the history of colors you used in a single call, that way you can actually nest colors like this:

ConsoleWriter.WriteLine("{FC=Magenta}This is magenta, {FC=Yellow}now yellow, {/FC}now back to magenta{/FC}, now back to default.");

This will output as: Nested colors output

I even like to use the actual enum in an interpolated string and it still works:

ConsoleWriter.WriteLine($"{{FC={ConsoleColor.Red}}}This works too!{{/FC}}");
public static void Write(string msg)
{
  if (string.IsNullOrEmpty(msg))
  {
    return;
  }

  var color_match = Regex.Match(msg, @"{[FB]C=[a‑z]+}|{\/[FB]C}", RegexOptions.IgnoreCase);
  if (color_match.Success)
  {
    var initial_background_color = Console.BackgroundColor;
    var initial_foreground_color = Console.ForegroundColor;
    var background_color_history = new List<ConsoleColor>();
    var foreground_color_history = new List<ConsoleColor>();

    var current_index = 0;

    while (color_match.Success)
    {
      if ((color_match.Index ‑ current_index) > 0)
      {
        Console.Write(msg.Substring(current_index, color_match.Index ‑ current_index));
      }

      if (color_match.Value.StartsWith("{BC=", StringComparison.OrdinalIgnoreCase)) // set background color
      {
        var background_color_name = GetColorNameFromMatch(color_match);
        Console.BackgroundColor = GetParsedColorAndAddToHistory(background_color_name, background_color_history, initial_background_color);
      }
      else if (color_match.Value.Equals("{/BC}", StringComparison.OrdinalIgnoreCase)) // revert background color
      {
        Console.BackgroundColor = GetLastColorAndRemoveFromHistory(background_color_history, initial_background_color);
      }
      else if (color_match.Value.StartsWith("{FC=", StringComparison.OrdinalIgnoreCase)) // set foreground color
      {
        var foreground_color_name = GetColorNameFromMatch(color_match);
        Console.ForegroundColor = GetParsedColorAndAddToHistory(foreground_color_name, foreground_color_history, initial_foreground_color);
      }
      else if (color_match.Value.Equals("{/FC}", StringComparison.OrdinalIgnoreCase)) // revert foreground color
      {
        Console.ForegroundColor = GetLastColorAndRemoveFromHistory(foreground_color_history, initial_foreground_color);
      }

      current_index = color_match.Index + color_match.Length;
      color_match = color_match.NextMatch();
    }

    Console.Write(msg.Substring(current_index));

    Console.BackgroundColor = initial_background_color;
    Console.ForegroundColor = initial_foreground_color;
  }
  else
  {
    Console.Write(msg);
  }
}

public static void WriteLine(string msg)
{
  Write(msg);
  Console.WriteLine();
}

private static string GetColorNameFromMatch(Match match)
{
  return match.Value.Substring(4, match.Value.IndexOf("}") ‑ 4);
}

private static ConsoleColor GetParsedColorAndAddToHistory(string colorName, List<ConsoleColor> colorHistory, ConsoleColor defaultColor)
{
  var new_color = Enum.TryParse<ConsoleColor>(colorName, true, out var parsed_color) ? parsed_color : defaultColor;
  colorHistory.Add(new_color);

  return new_color;
}

private static ConsoleColor GetLastColorAndRemoveFromHistory(List<ConsoleColor> colorHistory, ConsoleColor defaultColor)
{
  if (colorHistory.Any())
  {
    colorHistory.RemoveAt(colorHistory.Count ‑ 1);
  }

  return colorHistory.Any() ? colorHistory.Last() : defaultColor;
}

方法 3:

You can't use different colors within one Console.WriteLine() ‑ use Console.Write() instead.

Console.WriteLine("What is your name?");
string name = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("Your name is ");
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("name");
Console.WriteLine(); //linebreak
Console.ResetColor(); //reset to default values

方法 4:

It looks like Spectre Console does a lot of this magic for us and is inspired by the popular Rich Python library that does a similar thing.

Install Spectre Console:

dotnet add package Spectre.Console

Then use markup to specify colors inline, for example:

using Spectre.Console;

AnsiConsole.Markup("[maroon on blue]Hello[/]");

See documentation for more details: https://spectreconsole.net/markup

enter image description here

方法 5:

Another more reusable way is:

static void Main(string[] args)
{
    Write("True love is love for C#, my beloved programming language.", "love");
    Console.ReadLine();
}
static void Write(string text, string coloredWord)
{
    string[] normalParts = text.Split(new string[] { coloredWord }, StringSplitOptions.None);
    for (int i = 0; i < normalParts.Length; i++)
    {
        Console.ResetColor();
        Console.Write(normalParts[i]);
        if (i != normalParts.Length ‑ 1)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.Write(coloredWord);
        }
    }
}

Which gives you enter image description here

For marking only the word 'love' and not 'beloved', you can pass " love " to the method (with spaces) which gives you: enter image description here

(by RomshteynCaius JardJordan9232fuboJonathan B.Bamdad)

參考文件

  1. How to color words in different colours in a Console.WriteLine in a console application? (CC BY‑SA 2.5/3.0/4.0)

#console-application #C#






相關問題

如何在控制台應用程序中調用 Windows 服務? (How can I call a windows service in a console application?)

有沒有一種簡單的方法可以在 Java 中打印圖形菜單到控制台? (Is there an easy way to print a graphical menu to console in Java?)

控制台應用程序中的多個參數未正確解析 (Multiple args in Console Application not parsing correctly)

我可以從控制台應用程序中的 mvc 3 Web 應用程序獲取用戶 ID 嗎? (Can I get user id from mvc 3 web app in console app?)

是否可以從一個帶殼的進程中截獲控制台輸出? (Is it possible to intercept Console output from a shelled process?)

如何在 C# 的任務管理器中隱藏控制台應用程序? (How can I hide a console app in Task Manager in C#?)

實現一個通過 SSL 使用 WebServices 的 C# 客戶端? (Implement a C# Client that uses WebServices over SSL?)

異常未處理 - 重新拋出異常 (Exception was unhandled - rethrow exception)

如何在 C# Windows 控制台應用程序中執行命令? (How to execute command in a C# Windows console app?)

如何將子類中的方法傳遞給Java中的Main類 (How to pass methods in the child class to the Main class in Java)

為 C# 控制台應用程序添加背景音頻 (Adding background audio for a C# Console Application)

在 C# 控制台應用程序中更改數組中元素的索引,但運行時返回索引保持不變 (Changes index of elements in Array in a C# console app, but when runs it return index remain same)







留言討論