Powershell -replace đưa ra hành vi kỳ lạ
Điều này là lái xe cho tôi hạt! Xin vui lòng đánh giá cao bất kỳ gợi ý nào về những gì đang xảy ra!
$alpha = 'aaa.bbb.$connection.ccc.ddd'
$s = [regex]::match($alpha,"\$.+?(?=\.)").Value "Alpha is: $alpha"
"Matched chunk is: $s" $newChunk = "'" + $s + "'" "New chunk is: $newChunk"
$beta = $alpha -replace $s,$newChunk
"Beta is: $beta"
Điều này tạo ra kết quả sau:
Alpha is: aaa.bbb.$connection.ccc.ddd
Matched chunk is: $connection New chunk is: '$connection'
Beta is: aaa.bbb.$connection.ccc.ddd
Tôi đang cố gắng xác định / khớp các chuỗi ký tự trong một đường dẫn bắt đầu bằng chữ '$' và tiếp tục cho đến khi, nhưng không bao gồm dấu chấm theo nghĩa đen "." ký tự. Trong đoạn mã ví dụ trên, chuỗi sẽ là "$ connection".
Sau đó, tôi cần đặt chuỗi đó trong các dấu nháy đơn, vì vậy trong ví dụ trên, giá trị $ newChunk sẽ trở thành '$ kết nối' bao gồm các dấu nháy đơn.
Tiếp theo, tôi cần thay thế giá trị đã khớp bằng giá trị được trích dẫn đơn mới trong chuỗi ban đầu. Dù tôi có thử gì đi nữa (tương tự với [regex] :: match method), các dấu nháy đơn sẽ bị loại bỏ. Vì vậy, một cách hiệu quả, tôi đang cố gắng biến:
aaa.bbb.$connection.ccc.ddd
thành
aaa.bbb.'$connection'.ccc.ddd
Sử dụng Powershell 7.1 và thực sự đánh giá cao ai đó đã nói với tôi tại sao điều này không hoạt động. Cảm ơn!
Trả lời
Sử dụng
$beta = $alpha -replace '\$[^.]+', "'$&'"
Xem bằng chứng .
Giải trình
--------------------------------------------------------------------------------
\$ '$'
--------------------------------------------------------------------------------
[^.]+ any character except: '.' (1 or more times
(matching the most amount possible))
Là $&trình giữ chỗ cho toàn bộ trận đấu.
Câu trả lời hữu ích của Ryszard Czech chắc chắn là giải pháp tốt nhất : đề cập chung đến những gì toán tử dựa trên regex -replace phù hợp, trong toán hạng thay thế của nó, với trình giữ chỗ$& là giải pháp đơn giản và mạnh mẽ nhất.
Xem câu trả lời này cho các trình giữ chỗ khác mà bạn có thể sử dụng, chẳng hạn như những gì trước ( $`) hoặc thành công ( $') so khớp hoặc những gì một nhóm chụp đã khớp (ví dụ $1).
Đối với những gì bạn đã thử :
Thay vì sử dụng
\$.+?(?=\.)trực tiếp regex của bạn với toán tử dựa trên regex , bạn đã sử dụng kết quả nguyên văn của một lệnh gọi rõ ràng làm toán hạng tìm kiếm (toán hạng RHS đầu tiên) , sau đó lại được hiểu là regex.-replace[regex].Match()-replace- Tuy nhiên, để sử dụng nguyên văn một chuỗi làm toán hạng
-replacetìm kiếm , bất kỳ siêu ký tự regex nào - tức là, các ký tự có ý nghĩa cú pháp đặc biệt - phải được\ghi rõ , chẳng hạn như nguyên văn$trong chuỗi của bạn, bạn có thể thực hiện với[regex]::Escape($s)
- Tuy nhiên, để sử dụng nguyên văn một chuỗi làm toán hạng
Ngoài ra, bạn đã sử dụng một toán hạng thay thế có một ký tự được nhúng
$. mà bạn muốn được diễn giải nguyên văn , nhưng$trong toán hạng thay thế là một siêu ký tự , đề cập đến các trình giữ chỗ chẳng hạn như$&.Để sử dụng nguyên văn chuỗi làm toán hạng
-replacethay thế , bạn phải thoát các ký tự nhúng theo chương trình . như [1] : Phương pháp đơn giản nhất là sử dụng phương pháp thay thế theo nghĩa đen-substring của loại, :$$$[string].Replace()$replacementOperand = '$foo' 'value is: (value)' -replace '\(value\)', $replacementOperand.Replace('$', '$$')
Do đó, cách tiếp cận ban đầu của bạn sẽ phải sử dụng lệnh sau - nhưng lưu ý rằng giải pháp của Ryszard về tổng thể đơn giản hơn nhiều:
$beta = $alpha -replace [regex]::replace($s), $newChunk.Replace('$', '$$')
[1] Về mặt tình huống, bạn có thể thoát ra ngoài mà không thoát, vì $mã thông báo có tiền tố không được công nhận là trình giữ chỗ được giữ nguyên (ví dụ: 'bar' -replace 'r', '$x'hoạt động giống như 'bar' -replace 'r', '$$x'), nhưng giải pháp mạnh mẽ duy nhất là thoát các $ký tự nguyên văn . bằng cách nhân đôi chúng.