在PowerShell中替换字符串中的第一个匹配字符(Replace first matching character in string in PowerShell)

在下面的字符串中,

apache:x:48:48:Apache:/var/www:/sbin/nologin

我怎么能用逗号代替第一个冒号(只有这个冒号),这样我才能得到下面的字符串?

apache,x:48:48:Apache:/var/www:/sbin/nologin

此外,代码必须支持多行文件,并且只替换每行中的第一个逗号。

In the following string,

apache:x:48:48:Apache:/var/www:/sbin/nologin

how could I replace the first colon (and this one only) with a comma so I would get the following string?

apache,x:48:48:Apache:/var/www:/sbin/nologin

Also, the code has to support a file with multiple lines and replace the first comma in each line only.

最满意答案

使用正则表达式:

PS C:\> $s = 'apache:x:48:48:Apache:/var/www:/sbin/nologin'
PS C:\> $s -replace '^(.*?):(.*)','$1,$2'
apache,x:48:48:Apache:/var/www:/sbin/nologin 

正则表达式细分:

^(.*?):字符串开头和冒号(即第一个冒号前面的文本)之间的最短匹配。 (.*) :字符串的其余部分(即第一个冒号后的所有内容)。

这些派生类对子表达式进行分组,因此它们可以在替换字符串中被引用为$1和$2 。

进一步解释:

^匹配字符串的开头。 .*匹配任意数量的字符(。⇒任何字符, * ⇒零次或多次)。 .*? 做同样的事情,但给出了最短的匹配( ? )而不是最长的匹配。 这被称为“非贪婪匹配”。

Use a regular expression:

PS C:\> $s = 'apache:x:48:48:Apache:/var/www:/sbin/nologin'
PS C:\> $s -replace '^(.*?):(.*)','$1,$2'
apache,x:48:48:Apache:/var/www:/sbin/nologin 

Regexp breakdown:

^(.*?):: shortest match between the beginning of the string and a colon (i.e. the text before the first colon). (.*): the remainder of the string (i.e. everything after the first colon).

The parantheses group the subexpressions, so they can be referenced in the replacement string as $1 and $2.

Further explanation:

^ matches the beginning of a string. .* matches any number of characters (. ⇒ any character, * ⇒ zero or more times). .*? does the same, but gives the shortest match (?) instead of the longest match. This is called a "non-greedy match".在PowerShell中替换字符串中的第一个匹配字符(Replace first matching character in string in PowerShell)

在下面的字符串中,

apache:x:48:48:Apache:/var/www:/sbin/nologin

我怎么能用逗号代替第一个冒号(只有这个冒号),这样我才能得到下面的字符串?

apache,x:48:48:Apache:/var/www:/sbin/nologin

此外,代码必须支持多行文件,并且只替换每行中的第一个逗号。

In the following string,

apache:x:48:48:Apache:/var/www:/sbin/nologin

how could I replace the first colon (and this one only) with a comma so I would get the following string?

apache,x:48:48:Apache:/var/www:/sbin/nologin

Also, the code has to support a file with multiple lines and replace the first comma in each line only.

最满意答案

使用正则表达式:

PS C:\> $s = 'apache:x:48:48:Apache:/var/www:/sbin/nologin'
PS C:\> $s -replace '^(.*?):(.*)','$1,$2'
apache,x:48:48:Apache:/var/www:/sbin/nologin 

正则表达式细分:

^(.*?):字符串开头和冒号(即第一个冒号前面的文本)之间的最短匹配。 (.*) :字符串的其余部分(即第一个冒号后的所有内容)。

这些派生类对子表达式进行分组,因此它们可以在替换字符串中被引用为$1和$2 。

进一步解释:

^匹配字符串的开头。 .*匹配任意数量的字符(。⇒任何字符, * ⇒零次或多次)。 .*? 做同样的事情,但给出了最短的匹配( ? )而不是最长的匹配。 这被称为“非贪婪匹配”。

Use a regular expression:

PS C:\> $s = 'apache:x:48:48:Apache:/var/www:/sbin/nologin'
PS C:\> $s -replace '^(.*?):(.*)','$1,$2'
apache,x:48:48:Apache:/var/www:/sbin/nologin 

Regexp breakdown:

^(.*?):: shortest match between the beginning of the string and a colon (i.e. the text before the first colon). (.*): the remainder of the string (i.e. everything after the first colon).

The parantheses group the subexpressions, so they can be referenced in the replacement string as $1 and $2.

Further explanation:

^ matches the beginning of a string. .* matches any number of characters (. ⇒ any character, * ⇒ zero or more times). .*? does the same, but gives the shortest match (?) instead of the longest match. This is called a "non-greedy match".