@ -17,19 +17,19 @@ class ContentSearchService {
@@ -17,19 +17,19 @@ class ContentSearchService {
final queries = _splitQuery ( query ) ; / / 分 割 查 询 字 符 串
for ( final q in queries ) {
final pattern = _buildSearchPattern (
final pattern = _buildSearchPattern (
query: q ,
caseSensitive: caseSensitive ,
wholeWord: wholeWord ,
useRegex: useRegex ,
) ;
caseSensitive: caseSensitive ,
wholeWord: wholeWord ,
useRegex: useRegex ,
) ;
await for ( final entity in dir . list ( recursive: true ) ) {
if ( entity is File & & _matchesFileType ( entity . path , fileType ) ) {
await for ( final entity in dir . list ( recursive: true ) ) {
if ( entity is File & & _matchesFileType ( entity . path , fileType ) ) {
await _searchInFile ( entity , pattern , results , q ) ; / / 传 递 当 前 查 询 项
}
}
}
}
return results ;
}
@ -48,19 +48,19 @@ class ContentSearchService {
@@ -48,19 +48,19 @@ class ContentSearchService {
final queries = _splitQuery ( query ) ; / / 分 割 查 询 字 符 串
for ( final q in queries ) {
final pattern = _buildSearchPattern (
final pattern = _buildSearchPattern (
query: q ,
caseSensitive: caseSensitive ,
wholeWord: wholeWord ,
useRegex: useRegex ,
) ;
caseSensitive: caseSensitive ,
wholeWord: wholeWord ,
useRegex: useRegex ,
) ;
await for ( final entity in dir . list ( recursive: true ) ) {
if ( entity is File & & _matchesFileType ( entity . path , fileType ) ) {
await for ( final entity in dir . list ( recursive: true ) ) {
if ( entity is File & & _matchesFileType ( entity . path , fileType ) ) {
await _countInFile ( entity , pattern , counts , q ) ; / / 传 递 当 前 查 询 项
}
}
}
}
return counts ;
}
@ -89,11 +89,76 @@ class ContentSearchService {
@@ -89,11 +89,76 @@ class ContentSearchService {
return RegExp ( pattern , caseSensitive: caseSensitive , multiLine: true ) ;
}
/ / / 检 查 文 件 类 型 ( 原 逻 辑 不 变 )
static bool _matchesFileType ( String filePath , String fileType ) {
/ / 处 理 特 殊 情 况
if ( fileType = = ' *.* ' ) return true ;
final ext = path . extension ( filePath ) . toLowerCase ( ) ;
return ext = = fileType . toLowerCase ( ) ;
if ( fileType = = ' * ' ) return true ;
/ / 分 割 通 配 符 为 文 件 名 和 扩 展 名 部 分
final parts = fileType . split ( ' . ' ) ;
final patternName = parts . length > 0 ? parts [ 0 ] : ' ' ;
final patternExt = parts . length > 1 ? parts . sublist ( 1 ) . join ( ' . ' ) : ' ' ;
/ / 获 取 文 件 的 实 际 名 称 和 扩 展 名
final fileName = path . basename ( filePath ) ;
final fileExt = path . extension ( fileName ) . toLowerCase ( ) . replaceFirst ( ' . ' , ' ' ) ;
/ / 匹 配 文 件 名 部 分 ( 如 果 有 指 定 )
bool nameMatches = true ;
if ( patternName . isNotEmpty & & patternName ! = ' * ' ) {
nameMatches = _matchesWildcard ( fileName , patternName ) ;
}
/ / 匹 配 扩 展 名 部 分 ( 如 果 有 指 定 )
bool extMatches = true ;
if ( patternExt . isNotEmpty ) {
if ( patternExt = = ' * ' ) {
extMatches = true ;
} else {
extMatches = _matchesWildcard ( fileExt , patternExt ) ;
}
}
return nameMatches & & extMatches ;
}
/ / 辅 助 函 数 : 判 断 字 符 串 是 否 匹 配 通 配 符 模 式
static bool _matchesWildcard ( String input , String pattern ) {
/ / 处 理 特 殊 情 况
if ( pattern = = ' * ' ) return true ;
/ / 动 态 规 划 实 现 通 配 符 匹 配
final m = input . length ;
final n = pattern . length ;
final dp = List . generate ( m + 1 , ( _ ) = > List . filled ( n + 1 , false ) ) ;
/ / 空 字 符 串 匹 配 空 模 式
dp [ 0 ] [ 0 ] = true ;
/ / 处 理 模 式 以 * 开 头 的 情 况
for ( int j = 1 ; j < = n ; j + + ) {
if ( pattern [ j - 1 ] = = ' * ' ) {
dp [ 0 ] [ j ] = dp [ 0 ] [ j - 1 ] ;
}
}
/ / 填 充 动 态 规 划 表
for ( int i = 1 ; i < = m ; i + + ) {
for ( int j = 1 ; j < = n ; j + + ) {
if ( pattern [ j - 1 ] = = ' * ' ) {
/ / * 可 以 匹 配 任 意 字 符 或 空 字 符
dp [ i ] [ j ] = dp [ i ] [ j - 1 ] | | dp [ i - 1 ] [ j ] ;
} else if ( pattern [ j - 1 ] = = ' ? ' | | input [ i - 1 ] = = pattern [ j - 1 ] ) {
/ / ? 匹 配 单 个 字 符 , 或 者 字 符 直 接 相 等
dp [ i ] [ j ] = dp [ i - 1 ] [ j - 1 ] ;
} else {
/ / 不 匹 配
dp [ i ] [ j ] = false ;
}
}
}
return dp [ m ] [ n ] ;
}
/ / / 在 文 件 中 搜 索 匹 配 项 ( 增 加 queryTerm 参 数 )