如何使用FLEX实现日期类关键词的动态替换?
Got it, let's work through this date replacement problem together—totally get the frustration of scarce Flex examples online. Your current code has the right starting idea with pattern matching, but we need to fix the regex patterns and implement actual date calculation logic. Here's a step-by-step solution:
First, Fix the Flex Pattern Definitions
Your original patterns like TODAY+n are fixed strings, which won't match dynamic values like TODAY+5 or TODAY-3. We need to use regex to capture the numeric offset:
%{ // We'll add C includes and helper functions here later %} // Define regex patterns for each placeholder TODAY "TODAY" YESTERDAY "YESTERDAY" TOMORROW "TOMORROW" TODAY_PLUS "TODAY"[+][0-9]+ // Matches TODAY+1, TODAY+10, etc. TODAY_MINUS "TODAY"[-][0-9]+ // Matches TODAY-1, TODAY-7, etc.
Add Date Calculation Logic
We'll use C's time.h library to handle date arithmetic—this lets us easily add/subtract days and handle edge cases like month/year rollovers. Add this inside the %{ ... %} section at the top:
#include <stdio.h> #include <time.h> #include <stdlib.h> #include <string.h> // Helper function: Calculate date by adding `days` to current date // Returns a formatted string (YYYY-MM-DD) that must be freed char* calculate_date(int days) { time_t now = time(NULL); struct tm *current_tm = localtime(&now); // Adjust the day count current_tm->tm_mday += days; // mktime() automatically fixes invalid dates (e.g., Jan 31 +1 → Feb 1) mktime(current_tm); // Allocate memory for the formatted date string char *date_str = malloc(11 * sizeof(char)); // YYYY-MM-DD is 10 chars + null terminator strftime(date_str, 11, "%Y-%m-%d", current_tm); return date_str; }
Implement the Flex Actions
Now, update the rules section to replace each matched placeholder with the correct date. We also add a rule to output all non-matching characters so the rest of your text stays intact:
%% {TODAY} { char *date = calculate_date(0); fputs(date, stdout); free(date); // Don't forget to free the allocated memory! } {YESTERDAY} { char *date = calculate_date(-1); fputs(date, stdout); free(date); } {TOMORROW} { char *date = calculate_date(1); fputs(date, stdout); free(date); } {TODAY_PLUS} { // Extract the numeric offset: skip "TODAY+" (5 + 1 = 6 characters) int days = atoi(yytext + 6); char *date = calculate_date(days); fputs(date, stdout); free(date); } {TODAY_MINUS} { // Extract the numeric offset: skip "TODAY-" (5 + 1 = 6 characters) int days = atoi(yytext + 6); char *date = calculate_date(-days); fputs(date, stdout); free(date); } . { fputc(yytext[0], stdout); } // Output any unmatched characters as-is %%
Add Main and Wrap Functions
Finally, add the required main() and yywrap() functions to complete the program:
int main() { yylex(); return 0; } int yywrap() { return 1; // Signals end of input }
How to Compile and Run
- Save all this code in a file named
date_replace.l - Compile with Flex and GCC:
flex date_replace.l gcc lex.yy.c -o date_replace -lfl - Run it with your input text:
./date_replace < your_input.txt
Key Fixes from Your Original Code
- Dynamic Pattern Matching: Replaced fixed strings with regex to capture numeric offsets for
TODAY±n - Date Arithmetic: Used
time.hfunctions to handle proper date calculations (no manual month/year handling!) - Memory Management: Allocated and freed memory for the formatted date string to avoid leaks
- Preserve Original Text: Added the
.rule to output all non-matching characters so your original text isn't lost
内容的提问来源于stack exchange,提问作者NewbUser

