Change:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.73.0 OS Version: Windows 10 Enterprise 20H2 Steps to Reproduce: a file named with CRLF line endings and the following content: the editor tab. the Search: Replace in Files command. the following search expression: the Use Regular Expression option. the following replacement expression: The results preview will show an incorrect replacement for the second match: ! In the results preview, click one of the items to open the preview in an editor. You see the incorrect replacement there, too: ! the preview editor tab. This temporarily fixes the results preview. the search field into focus, then press Enter to rerun the search. The incorrect preview from step 6 reappears. the Replace All icon and watch the incorrect replacement propagate to in the file system. Expected result: Actual result: Log (Window) output, trace level, some details redacted: Log (Extension host) output, trace level, some details redacted: I’m aware of the page, especially the and the fact that the project tries to support CRLF in searches on a best-effort basis anyway. However, given: how widespread CRLF still is in many projects; the fact that using a literal line break (Ctrl+Enter) instead of the doesn’t help; and the fact that this can cause subtle data corruption, which may go unnoticed for a long time, I thought I’d bring this to your attention. Also, please note that this is different from issue .
Thanks for creating this issue! It looks like you may be using an old version of VS Code, the latest stable release is 1.73.0. Please try upgrading to the latest version and checking whether this issue remains. Happy Coding!
The issue persists in version 1.73.0.
Thanks for the good repro steps, claui!

Discussion:
const fullMatchText = this.fullMatchText(); let replaceString = searchModel.replacePattern.getReplaceString(fullMatchText, searchModel.preserveCase); <ins> if (replaceString !== null) { return replaceString; } </ins> <del> // If match string is not matching then regex pattern has a lookahead expression if (replaceString === null) { const fullMatchTextWithSurroundingContent = this.fullMatchText(true); replaceString = searchModel.replacePattern.getReplaceString(fullMatchTextWithSurroundingContent, searchModel.preserveCase); // Search/find normalize line endings - check whether r prevents regex from matching if (replaceString === null) { const fullMatchTextWithoutCR = fullMatchTextWithSurroundingContent.replace(/rn/g, 'n'); replaceString = searchModel.replacePattern.getReplaceString(fullMatchTextWithoutCR, searchModel.preserveCase); </del> <ins> // Search/find normalize line endings - check whether r prevents regex from matching const fullMatchTextWithoutCR = fullMatchText.replace(/rn/g, 'n'); if (fullMatchTextWithoutCR !== fullMatchText) { replaceString = searchModel.replacePattern.getReplaceString(fullMatchTextWithoutCR, searchModel.preserveCase); if (replaceString !== null) { return replaceString; </ins> } } <del> // Match string is still not matching. Could be unsupported matches (multi-line). if (replaceString === null) { replaceString = searchModel.replacePattern.pattern; </del> <ins> // If match string is not matching then regex pattern has a lookahead expression const contextMatchTextWithSurroundingContent = this.fullMatchText(true); replaceString = searchModel.replacePattern.getReplaceString(contextMatchTextWithSurroundingContent, searchModel.preserveCase); if (replaceString !== null) { return replaceString; } // Search/find normalize line endings, this time in full context const contextMatchTextWithoutCR = contextMatchTextWithSurroundingContent.replace(/rn/g, 'n'); if (contextMatchTextWithoutCR !== contextMatchTextWithSurroundingContent) { replaceString = searchModel.replacePattern.getReplaceString(contextMatchTextWithoutCR, searchModel.preserveCase); if (replaceString !== null) { return replaceString; } </ins> } <del> return replaceString; </del> <ins> // Match string is still not matching. Could be unsupported matches (multi-line). return searchModel.replacePattern.pattern; </ins> } fullMatchText(includeSurrounding = false): string {