使用正则表达式拆分字符串似乎不如预期的那样工作。

huangapple go评论92阅读模式
英文:

Spliting Strings by regex seems not to work as expected

问题

在PowerShell中有一个函数:

  1. function WriteToLog {
  2. [CmdletBinding()]
  3. param(
  4. [Parameter(Mandatory, ValueFromPipeline)]
  5. [AllowEmptyCollection()]
  6. [AllowEmptyString()]
  7. [string[]]$Message
  8. )
  9. BEGIN {}
  10. PROCESS {
  11. if ($Null -ne $Message) {
  12. $dt = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
  13. foreach ($item in $Message) {
  14. if ($item.length -gt 0) {
  15. $it = $item -split '(.{1,70})' | Where-Object {$_}
  16. $dt + ": " + $it[0] | Write-Host
  17. $dt = $dt -replace '(.)',' '
  18. $i = 1
  19. while ($it[$i]) {
  20. $dt + " " + $it[$i] | Write-Host
  21. $i++
  22. }
  23. }
  24. }
  25. }
  26. }
  27. END {}
  28. }

现在使用字符串调用它:

  1. "----" | WriteToLog

输出:

  1. 2023-05-25 00:28:05: -
  2. -
  3. -
  4. -
  5. -

我希望的是:

  1. 2023-05-25 00:28:05: -----

而不是将字符串拆分成字符。
如果字符串长度超过70个字符,它会按预期工作:

  1. "--------------------------------------------------------------------------" | WriteToLog

输出:

  1. 2023-05-25 00:32:37: ----------------------------------------------------------------------
  2. ----

有任何想法为什么会这样?

英文:

Having a function in PowerShell:

  1. function WriteToLog {
  2. [CmdletBinding()]
  3. param(
  4. [Parameter(Mandatory, ValueFromPipeline)]
  5. [AllowEmptyCollection()]
  6. [AllowEmptyString()]
  7. [string[]]$Message
  8. )
  9. BEGIN {}
  10. PROCESS {
  11. if ($Null -ne $Message) {
  12. $dt = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
  13. foreach ($item in $Message) {
  14. if ($item.length -gt 0) {
  15. $it = $item -split '(.{1,70})' | Where-Object {$_}
  16. $dt + ": " + $it[0] | Write-Host
  17. $dt = $dt -replace '(.)',' '
  18. $i = 1
  19. while ($it[$i]) {
  20. $dt + " " + $it[$i] | Write-Host
  21. $i++
  22. }
  23. }
  24. }
  25. }
  26. }
  27. END {}
  28. }

Now calling it with a string:

  1. "----" | WriteToLog

gives:

  1. 2023-05-25 00:28:05: -
  2. -
  3. -
  4. -
  5. -

I'd expected:

  1. 2023-05-25 00:28:05: -----

Not splitting the string in characters.
With a string longer than 70 characters it works as expected:

  1. "--------------------------------------------------------------------------" | WriteToLog

gives:

  1. 2023-05-25 00:32:37: ----------------------------------------------------------------------
  2. ----

Any idea why this happens?

答案1

得分: 1

将您的正则表达式更改为 '(?<=\G.{70})',这样只有在字符计数为 70 时才会拆分,还使用了正向回顾与 \G,消除了过滤非空字符串的需要 (Where-Object { $_ })。另外,条件 if ($Null -ne $Message) 是不必要的,您已经在枚举集合并检查 if ($item.Length -gt 0)

  1. function WriteToLog {
  2. [CmdletBinding()]
  3. param(
  4. [Parameter(Mandatory, ValueFromPipeline)]
  5. [AllowEmptyCollection()]
  6. [AllowEmptyString()]
  7. [string[]] $Message
  8. )
  9. process {
  10. $dt = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss')
  11. foreach ($item in $Message) {
  12. if ($item.Length -gt 0) {
  13. $it = $item -split '(?<=\G.{70})'
  14. $dt + ': ' + $it[0] | Write-Host
  15. $dt = [string]::new(' ', $dt.Length)
  16. for($i = 1; $i -lt $it.Length; $i++) {
  17. $dt + ' ' + $it[$i] | Write-Host
  18. }
  19. }
  20. }
  21. }
  22. }
  23. '---------------------------------------------------------------------------' | WriteToLog
  24. '-----' | WriteToLog
  25. WriteToLog '', ''
英文:

Change your regex to &#39;(?&lt;=\G.{70})&#39; so it only splits if the char count is 70, also using a positive lookbehind with \G removes the need to filter where the token is not an empty string (Where-Object { $_ }). Also the condition if ($Null -ne $Message) is unnecessary, you're already enumerating the collection and checking if ($item.Length -gt 0).

  1. function WriteToLog {
  2. [CmdletBinding()]
  3. param(
  4. [Parameter(Mandatory, ValueFromPipeline)]
  5. [AllowEmptyCollection()]
  6. [AllowEmptyString()]
  7. [string[]] $Message
  8. )
  9. process {
  10. $dt = (Get-Date).ToString(&#39;yyyy-MM-dd HH:mm:ss&#39;)
  11. foreach ($item in $Message) {
  12. if ($item.Length -gt 0) {
  13. $it = $item -split &#39;(?&lt;=\G.{70})&#39;
  14. $dt + &#39;: &#39; + $it[0] | Write-Host
  15. $dt = [string]::new(&#39; &#39;, $dt.Length)
  16. for($i = 1; $i -lt $it.Length; $i++) {
  17. $dt + &#39; &#39; + $it[$i] | Write-Host
  18. }
  19. }
  20. }
  21. }
  22. }
  23. &#39;---------------------------------------------------------------------------&#39; | WriteToLog
  24. &#39;-----&#39; | WriteToLog
  25. WriteToLog &#39;&#39;, &#39;&#39;

huangapple
  • 本文由 发表于 2023年5月25日 06:39:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76327822.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定