Flex程序空格处理及CR LF换行符异常问题求助
Hey there! Let's figure out what's going on with your Flex program and that newline issue in Notepad++.
First, let's clarify what CR LF means. CR stands for Carriage Return (\r, ASCII 13) and LF stands for Line Feed (\n, ASCII 10). Windows uses this two-character combination to mark the end of a line, while Unix-like systems (Linux, macOS) only use LF. Notepad++ shows "CR LF" to indicate the Windows-style line endings in your file.
Now, onto why your rule is breaking the line endings. In Flex, the [[:space:]] character class includes all whitespace characters—including \r (the CR part of your line ending). Here's the sequence that's causing trouble:
- Your input file uses Windows-style
\r\nline endings. - Flex treats
\nas the default line terminator, so when it reads a line, the\ris considered part of the line's content (not the terminator). - Your second rule
[[:space:]]+$matches the trailing whitespace at the end of the line, which includes that\rcharacter. - When you replace it with
printf("\n");, you're replacing the original\r\nwith just\n—turning Windows line endings into Unix-style ones. This mismatch throws off subsequent processing because the line structure is now different.
To fix this, we need to adjust your Flex rules to respect Windows line endings and avoid altering them. Here are two solid approaches:
Approach 1: Tell Flex to recognize CR LF as a single line terminator
Add the %option crlf directive at the top of your Flex code. This tells Flex to treat \r\n as one unified line terminator, so the \r won't be considered part of the line's content anymore. Then, modify your rules to preserve the original line ending format:
%option crlf %% ^[[:space:]]+ {} // Delete leading whitespace [[:space:]]+$ {} // Delete trailing whitespace (no line ending replacement) [[:space:]]+ {printf(" ");} // Collapse multiple spaces into one \n {printf("\r\n");} // Output Windows-style line ending . {ECHO;} // Print all other characters as-is %%
Approach 2: Exclude CR from your trailing whitespace match
If you don't want to change Flex's line terminator behavior, adjust your second rule to explicitly exclude the \r character from the trailing whitespace match. This way, you won't accidentally replace the CR part of the line ending:
%% ^[[:space:]]+ {} // Delete leading whitespace [[:space:]--[\r]]+$ {} // Delete trailing whitespace (excluding CR) [[:space:]]+ {printf(" ");} // Collapse multiple spaces into one \r\n {printf("\r\n");} // Preserve Windows line endings . {ECHO;} // Print all other characters as-is %%
A quick note: Your original rules didn't explicitly handle non-whitespace characters. Adding . {ECHO;} ensures that any characters not matched by your whitespace rules are printed exactly as they are—this prevents unexpected loss of content.
内容的提问来源于stack exchange,提问作者Edyssey

