예제 #1
0
        private IEnumerable <GrepMatch> TextSearchIterator(int lineNumber, int filePosition, string text, string searchText, GrepSearchOption searchOptions)
        {
            var lineEndIndexes = GetLineEndIndexes(initParams.VerboseMatchCount && lineNumber == -1 ? text : null);

            bool             isWholeWord    = searchOptions.HasFlag(GrepSearchOption.WholeWord);
            StringComparison comparisonType = searchOptions.HasFlag(GrepSearchOption.CaseSensitive) ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase;

            if (searchOptions.HasFlag(GrepSearchOption.BooleanOperators))
            {
                Utils.ParseBooleanOperators(searchText, out List <string> andClauses, out List <string> orClauses);

                if (andClauses != null && andClauses.Count > 1)
                {
                    return(TextSearchIteratorAnd(lineNumber, filePosition,
                                                 text, andClauses, lineEndIndexes, isWholeWord, comparisonType));
                }

                if (orClauses != null && orClauses.Count > 1)
                {
                    return(TextSearchIteratorOr(lineNumber, filePosition,
                                                text, orClauses, lineEndIndexes, isWholeWord, comparisonType));
                }
            }

            return(TextSearchIterator(lineNumber, filePosition, text, searchText, lineEndIndexes, isWholeWord, comparisonType));
        }
예제 #2
0
        private IEnumerable <GrepMatch> TextSearchIterator(int lineNumber, int filePosition, string text, string searchText, GrepSearchOption searchOptions)
        {
            var lineEndIndexes = GetLineEndIndexes(initParams.VerboseMatchCount && lineNumber == -1 ? text : null);

            int              index          = 0;
            bool             isWholeWord    = searchOptions.HasFlag(GrepSearchOption.WholeWord);
            StringComparison comparisonType = searchOptions.HasFlag(GrepSearchOption.CaseSensitive) ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase;

            while (index >= 0)
            {
                index = text.IndexOf(searchText, index, comparisonType);
                if (index >= 0)
                {
                    if (isWholeWord && (!Utils.IsValidBeginText(text.Substring(0, index)) ||
                                        !Utils.IsValidEndText(text.Substring(index + searchText.Length))))
                    {
                        index++;
                        continue;
                    }

                    if (initParams.VerboseMatchCount && lineEndIndexes.Count > 0)
                    {
                        lineNumber = lineEndIndexes.FindIndex(i => i > index) + 1;
                    }

                    yield return(new GrepMatch(lineNumber, index + filePosition, searchText.Length));

                    index++;
                }
            }
        }
예제 #3
0
        private IEnumerable <GrepMatch> RegexSearchIterator(int lineNumber, int filePosition, string text,
                                                            string searchPattern, GrepSearchOption searchOptions)
        {
            RegexOptions regexOptions = RegexOptions.None;

            if (!searchOptions.HasFlag(GrepSearchOption.CaseSensitive))
            {
                regexOptions |= RegexOptions.IgnoreCase;
            }
            if (searchOptions.HasFlag(GrepSearchOption.Multiline))
            {
                regexOptions |= RegexOptions.Multiline;
            }
            if (searchOptions.HasFlag(GrepSearchOption.SingleLine))
            {
                regexOptions |= RegexOptions.Singleline;
            }

            bool isWholeWord = searchOptions.HasFlag(GrepSearchOption.WholeWord);

            if (searchOptions.HasFlag(GrepSearchOption.BooleanOperators))
            {
                BooleanExpression exp = new BooleanExpression();
                if (exp.TryParse(searchPattern))
                {
                    return(RegexSearchIteratorBoolean(lineNumber, filePosition,
                                                      text, exp, isWholeWord, regexOptions));
                }
            }

            return(RegexSearchIterator(lineNumber, filePosition, text, searchPattern, isWholeWord, regexOptions));
        }
예제 #4
0
        public bool Replace(Stream readStream, Stream writeStream, string searchPattern, string replacePattern, SearchType searchType,
                            GrepSearchOption searchOptions, Encoding encoding, IEnumerable <GrepMatch> replaceItems)
        {
            SearchDelegates.DoReplace replaceMethod = DoTextReplace;
            switch (searchType)
            {
            case SearchType.PlainText:
                replaceMethod = DoTextReplace;
                break;

            case SearchType.Regex:
                replaceMethod = DoRegexReplace;
                break;

            case SearchType.XPath:
                replaceMethod = DoXPathReplace;
                break;

            case SearchType.Soundex:
                replaceMethod = DoFuzzyReplace;
                break;
            }

            if (searchOptions.HasFlag(GrepSearchOption.Multiline) || searchType == SearchType.XPath)
            {
                return(ReplaceMultiline(readStream, writeStream, searchPattern, replacePattern, searchOptions, replaceMethod, encoding, replaceItems));
            }
            else
            {
                return(Replace(readStream, writeStream, searchPattern, replacePattern, searchOptions, replaceMethod, encoding, replaceItems));
            }
        }
예제 #5
0
        public List <GrepSearchResult> Search(Stream input, string fileName, string searchPattern, SearchType searchType, GrepSearchOption searchOptions, Encoding encoding)
        {
            SearchDelegates.DoSearch searchMethod = DoTextSearch;
            switch (searchType)
            {
            case SearchType.PlainText:
                searchMethod = DoTextSearch;
                break;

            case SearchType.Regex:
                searchMethod = DoRegexSearch;
                break;

            case SearchType.XPath:
                searchMethod = DoXPathSearch;
                break;

            case SearchType.Soundex:
                searchMethod = DoFuzzySearch;
                break;
            }

            if (searchOptions.HasFlag(GrepSearchOption.Multiline) || searchType == SearchType.XPath)
            {
                return(SearchMultiline(input, fileName, searchPattern, searchOptions, searchMethod, encoding));
            }
            else
            {
                return(Search(input, fileName, searchPattern, searchOptions, searchMethod, encoding));
            }
        }
예제 #6
0
        public List <GrepSearchResult> CaptureGroupSearch(IEnumerable <string> files, string filePatternInclude,
                                                          GrepSearchOption searchOptions, SearchType searchType, string searchPattern, int codePage)
        {
            searchResults.Clear();

            if (files == null || !files.Any())
            {
                return(searchResults);
            }

            Utils.CancelSearch = false;

            try
            {
                foreach (string filePath in files)
                {
                    string fileName         = Path.GetFileName(filePath);
                    string modSearchPattern = Regex.Replace(fileName, filePatternInclude, searchPattern,
                                                            RegexOptions.IgnoreCase, TimeSpan.FromSeconds(4.0));

                    if (string.IsNullOrEmpty(modSearchPattern))
                    {
                        continue;
                    }
                    else if (searchType == SearchType.Regex && !Utils.ValidateRegex(modSearchPattern))
                    {
                        logger.Error($"Capture group search pattern is not a valid regular expression: '{modSearchPattern}'");
                        continue;
                    }

                    Search(filePath, searchType, modSearchPattern, searchOptions, codePage);

                    if (searchOptions.HasFlag(GrepSearchOption.StopAfterFirstMatch) && searchResults.Count > 0)
                    {
                        break;
                    }

                    if (Utils.CancelSearch)
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Failed in capture group search");
            }
            finally
            {
                if (cancellationTokenSource != null)
                {
                    cancellationTokenSource.Dispose();
                    cancellationTokenSource = null;
                }
                GrepEngineFactory.UnloadEngines();
            }
            return(new List <GrepSearchResult>(searchResults));
        }
예제 #7
0
파일: GrepCore.cs 프로젝트: dnGrep/dnGrep
        public List <GrepSearchResult> ListFiles(IEnumerable <FileData> files, GrepSearchOption searchOptions, int codePage)
        {
            searchResults.Clear();

            if (files == null)
            {
                return(searchResults);
            }

            int successful = 0;

            foreach (FileData fileInfo in files)
            {
                ProcessedFile(this, new ProgressStatus(true, searchResults.Count, successful, null, fileInfo.FullName));

                Encoding encoding = Encoding.Default;
                if (codePage > -1)
                {
                    encoding = Encoding.GetEncoding(codePage);
                }

                try
                {
                    if (GrepSettings.Instance.Get <bool>(GrepSettings.Key.DetectEncodingForFileNamePattern))
                    {
                        if (codePage == -1 && !fileInfo.FullName.Contains(ArchiveDirectory.ArchiveSeparator) &&
                            !Utils.IsArchive(fileInfo.FullName) && !Utils.IsBinary(fileInfo.FullName) &&
                            !Utils.IsPdfFile(fileInfo.FullName))
                        {
                            encoding = Utils.GetFileEncoding(fileInfo.FullName);
                        }
                    }

                    searchResults.Add(new GrepSearchResult(fileInfo, encoding));
                    successful++;
                }
                catch (Exception ex)
                {
                    // will catch file not found errors (Everything search):
                    logger.Error(ex, "Failed in ListFiles");
                    fileInfo.ErrorMsg = ex.Message;
                    AddSearchResult(new GrepSearchResult(fileInfo, encoding));
                }

                if (searchOptions.HasFlag(GrepSearchOption.StopAfterFirstMatch))
                {
                    break;
                }
                if (Utils.CancelSearch)
                {
                    break;
                }
            }

            ProcessedFile(this, new ProgressStatus(false, searchResults.Count, successful, searchResults, null));

            return(new List <GrepSearchResult>(searchResults));
        }
예제 #8
0
        private IEnumerable <GrepMatch> TextSearchIterator(int lineNumber, int filePosition, string text, string searchText, GrepSearchOption searchOptions)
        {
            var lineEndIndexes = GetLineEndIndexes(initParams.VerboseMatchCount && lineNumber == -1 ? text : null);

            bool             isWholeWord    = searchOptions.HasFlag(GrepSearchOption.WholeWord);
            StringComparison comparisonType = searchOptions.HasFlag(GrepSearchOption.CaseSensitive) ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase;

            if (searchOptions.HasFlag(GrepSearchOption.BooleanOperators))
            {
                BooleanExpression exp = new BooleanExpression();
                if (exp.TryParse(searchText))
                {
                    return(TextSearchIteratorBoolean(lineNumber, filePosition,
                                                     text, exp, lineEndIndexes, isWholeWord, comparisonType));
                }
            }

            return(TextSearchIterator(lineNumber, filePosition, text, searchText, lineEndIndexes, isWholeWord, comparisonType));
        }
예제 #9
0
        private IEnumerable <GrepMatch> RegexSearchIterator(int lineNumber, int filePosition, string text,
                                                            string searchPattern, GrepSearchOption searchOptions)
        {
            RegexOptions regexOptions = RegexOptions.None;

            if (!searchOptions.HasFlag(GrepSearchOption.CaseSensitive))
            {
                regexOptions |= RegexOptions.IgnoreCase;
            }
            if (searchOptions.HasFlag(GrepSearchOption.Multiline))
            {
                regexOptions |= RegexOptions.Multiline;
            }
            if (searchOptions.HasFlag(GrepSearchOption.SingleLine))
            {
                regexOptions |= RegexOptions.Singleline;
            }

            bool isWholeWord = searchOptions.HasFlag(GrepSearchOption.WholeWord);

            if (searchOptions.HasFlag(GrepSearchOption.BooleanOperators))
            {
                Utils.ParseBooleanOperators(searchPattern, out List <string> andClauses, out List <string> orClauses);

                if (andClauses != null && andClauses.Count > 1)
                {
                    return(RegexSearchIteratorAnd(lineNumber, filePosition,
                                                  text, andClauses, isWholeWord, regexOptions));
                }

                if (orClauses != null && orClauses.Count > 1)
                {
                    return(RegexSearchIteratorOr(lineNumber, filePosition,
                                                 text, orClauses, isWholeWord, regexOptions));
                }
            }

            return(RegexSearchIterator(lineNumber, filePosition, text, searchPattern, isWholeWord, regexOptions));
        }
예제 #10
0
        private IEnumerable <GrepMatch> FuzzySearchIterator(int lineNumber, int filePosition, string text, string searchPattern, GrepSearchOption searchOptions)
        {
            var lineEndIndexes = GetLineEndIndexes(initParams.VerboseMatchCount && lineNumber == -1 ? text : null);

            if (fuzzyMatchEngine == null)
            {
                fuzzyMatchEngine = new GoogleMatch();
            }
            fuzzyMatchEngine.Match_Threshold = initParams.FuzzyMatchThreshold;

            bool isWholeWord = searchOptions.HasFlag(GrepSearchOption.WholeWord);

            int counter = 0;

            while (counter < text.Length)
            {
                int matchLocation = fuzzyMatchEngine.match_main(text.Substring(counter), searchPattern, counter);
                if (matchLocation == -1)
                {
                    break;
                }

                if (isWholeWord && !Utils.IsValidBeginText(text.Substring(counter).Substring(0, matchLocation)))
                {
                    counter = counter + matchLocation + searchPattern.Length;
                    continue;
                }

                int matchLength = fuzzyMatchEngine.match_length(text.Substring(counter), searchPattern, matchLocation, isWholeWord, initParams.FuzzyMatchThreshold);

                if (matchLength == -1)
                {
                    counter = counter + matchLocation + searchPattern.Length;
                    continue;
                }

                if (initParams.VerboseMatchCount && lineEndIndexes.Count > 0)
                {
                    lineNumber = lineEndIndexes.FindIndex(i => i > matchLocation + counter) + 1;
                }

                yield return(new GrepMatch(searchPattern, lineNumber, matchLocation + filePosition + counter, matchLength));

                counter = counter + matchLocation + matchLength;
            }
        }
예제 #11
0
        protected string DoRegexReplace(int lineNumber, int filePosition, string text, string searchPattern, string replacePattern,
                                        GrepSearchOption searchOptions, IEnumerable <GrepMatch> replaceItems)
        {
            string result = text;

            RegexOptions regexOptions = RegexOptions.None;

            if (!searchOptions.HasFlag(GrepSearchOption.CaseSensitive))
            {
                regexOptions |= RegexOptions.IgnoreCase;
            }
            if (searchOptions.HasFlag(GrepSearchOption.Multiline))
            {
                regexOptions |= RegexOptions.Multiline;
            }
            if (searchOptions.HasFlag(GrepSearchOption.SingleLine))
            {
                regexOptions |= RegexOptions.Singleline;
            }

            bool isWholeWord = searchOptions.HasFlag(GrepSearchOption.WholeWord);

            if (isWholeWord)
            {
                if (!searchPattern.Trim().StartsWith("\\b"))
                {
                    searchPattern = "\\b" + searchPattern.Trim();
                }
                if (!searchPattern.Trim().EndsWith("\\b"))
                {
                    searchPattern = searchPattern.Trim() + "\\b";
                }
            }

            // check this block of text for any matches that are marked for replace
            // just return the original text if not
            var matches = RegexSearchIterator(lineNumber, filePosition, text, searchPattern, searchOptions);
            var toDo    = replaceItems.Intersect(matches);

            if (toDo.Any(r => r.ReplaceMatch))
            {
                // Issue #210 .net regex will only match the $ end of line token with a \n, not \r\n or \r
                bool   convertToWindowsNewline = false;
                string searchPatternForReplace = searchPattern;
                if (searchPattern.Contains("$") && text.Contains("\r\n"))
                {
                    convertToWindowsNewline = true;
                    searchPatternForReplace = searchPattern.Replace("\r\n", "\n");
                    replacePattern          = replacePattern.Replace("\r\n", "\n");
                    text = text.Replace("\r\n", "\n");
                }

                // because we're possibly altering the new line chars, the match.Index in Regex.Replace
                // may not match the startPos in the GrepMatch, but the order of the matches should be
                // the same.  So get the indexes of matches to change in this text block
                var indexes = toDo.Select((item, index) => new { item, index }).Where(t => t.item.ReplaceMatch).Select(t => t.index).ToList();

                int    matchIndex  = 0;
                string replaceText = Regex.Replace(text, searchPatternForReplace, (match) =>
                {
                    if (indexes.Contains(matchIndex++))
                    {
                        var pattern = DoPatternReplacement(match.Value, replacePattern);
                        return(match.Result(pattern));
                    }
                    else
                    {
                        return(match.Value);
                    }
                },
                                                   regexOptions, MatchTimeout);

                if (convertToWindowsNewline)
                {
                    replaceText = replaceText.Replace("\n", "\r\n");
                }

                result = replaceText;
            }

            return(result);
        }
예제 #12
0
        private void Search(string file, SearchType searchType, string searchPattern, GrepSearchOption searchOptions, int codePage)
        {
            try
            {
                ProcessedFile(this, new ProgressStatus(true, processedFilesCount, foundfilesCount, null, file));

                IGrepEngine engine = GrepEngineFactory.GetSearchEngine(file, SearchParams, FileFilter);

                Interlocked.Increment(ref processedFilesCount);

                bool isArchive = file.Contains(ArchiveDirectory.ArchiveSeparator);

                Encoding encoding = Encoding.Default;
                if (codePage > -1)
                {
                    encoding = Encoding.GetEncoding(codePage);
                }
                else if (!isArchive && !Utils.IsBinary(file) && !Utils.IsPdfFile(file))
                {
                    encoding = Utils.GetFileEncoding(file);
                }

                if (Utils.CancelSearch)
                {
                    if (cancellationTokenSource != null)
                    {
                        cancellationTokenSource.Cancel();
                    }
                    return;
                }

                List <GrepSearchResult> fileSearchResults = null;
                if (isArchive)
                {
                    fileSearchResults = ArchiveEngine.Search(engine, file, searchPattern, searchType, searchOptions, encoding);
                }
                else
                {
                    fileSearchResults = engine.Search(file, searchPattern, searchType, searchOptions, encoding);
                }

                if (fileSearchResults != null && fileSearchResults.Count > 0)
                {
                    AddSearchResults(fileSearchResults);
                }
                int hits = fileSearchResults.Where(r => r.IsSuccess).Count();
                Interlocked.Add(ref foundfilesCount, hits);

                ProcessedFile(this, new ProgressStatus(false, processedFilesCount, foundfilesCount, fileSearchResults, file));

                GrepEngineFactory.ReturnToPool(file, engine);
            }
            catch (Exception ex)
            {
                logger.Log <Exception>(LogLevel.Error, ex.Message, ex);
                AddSearchResult(new GrepSearchResult(file, searchPattern, ex.Message, false));
                if (ProcessedFile != null)
                {
                    List <GrepSearchResult> _results = new List <GrepSearchResult>
                    {
                        new GrepSearchResult(file, searchPattern, ex.Message, false)
                    };
                    ProcessedFile(this, new ProgressStatus(false, processedFilesCount, foundfilesCount, _results, file));
                }
            }
            finally
            {
                if (searchOptions.HasFlag(GrepSearchOption.StopAfterFirstMatch) && searchResults.Count > 0)
                {
                    if (cancellationTokenSource != null)
                    {
                        cancellationTokenSource.Cancel();
                    }
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Searches folder for files whose content matches regex
        /// </summary>
        /// <param name="files">Files to search in. If one of the files does not exist or is open, it is skipped.</param>
        /// <param name="searchRegex">Regex pattern</param>
        /// <returns>List of results. If nothing is found returns empty list</returns>
        public List <GrepSearchResult> Search(IEnumerable <string> files, SearchType searchType, string searchPattern, GrepSearchOption searchOptions, int codePage)
        {
            searchResults.Clear();

            if (files == null)
            {
                return(searchResults);
            }

            Utils.CancelSearch = false;

            if (searchPattern == null || searchPattern.Trim() == "")
            {
                int count = 0;
                foreach (string file in files)
                {
                    count++;
                    ProcessedFile(this, new ProgressStatus(true, searchResults.Count, count, null, file));

                    Encoding encoding = Encoding.Default;
                    if (codePage > -1)
                    {
                        encoding = Encoding.GetEncoding(codePage);
                    }

                    try
                    {
                        if (GrepSettings.Instance.Get <bool>(GrepSettings.Key.DetectEncodingForFileNamePattern))
                        {
                            if (codePage == -1 && !Utils.IsArchive(file) && !Utils.IsBinary(file) && !Utils.IsPdfFile(file))
                            {
                                encoding = Utils.GetFileEncoding(file);
                            }
                        }

                        searchResults.Add(new GrepSearchResult(file, searchPattern, null, encoding));
                    }
                    catch (Exception ex)
                    {
                        // will catch file not found errors (Everything search):
                        logger.Error(ex, "Failed in File Search");
                        AddSearchResult(new GrepSearchResult(file, searchPattern, ex.Message, false));
                    }

                    if (searchOptions.HasFlag(GrepSearchOption.StopAfterFirstMatch))
                    {
                        break;
                    }
                    if (Utils.CancelSearch)
                    {
                        break;
                    }
                }

                ProcessedFile(this, new ProgressStatus(false, searchResults.Count, count, searchResults, null));

                return(new List <GrepSearchResult>(searchResults));
            }
            else
            {
                processedFilesCount = 0;
                foundfilesCount     = 0;

                try
                {
                    if (SearchParams.SearchParallel)
                    {
                        cancellationTokenSource = new CancellationTokenSource();

                        ParallelOptions po = new ParallelOptions
                        {
                            MaxDegreeOfParallelism = Math.Max(1, Environment.ProcessorCount * 4 / 5),
                            CancellationToken      = cancellationTokenSource.Token
                        };
                        Parallel.ForEach(files, po, f => Search(f, searchType, searchPattern, searchOptions, codePage));
                    }
                    else
                    {
                        foreach (var file in files)
                        {
                            Search(file, searchType, searchPattern, searchOptions, codePage);

                            if (searchOptions.HasFlag(GrepSearchOption.StopAfterFirstMatch) && searchResults.Count > 0)
                            {
                                break;
                            }

                            if (Utils.CancelSearch)
                            {
                                break;
                            }
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    // expected for stop after first match or user cancel
                }
                catch (Exception ex)
                {
                    logger.Error(ex, "Failed in search in files");
                }
                finally
                {
                    if (cancellationTokenSource != null)
                    {
                        cancellationTokenSource.Dispose();
                        cancellationTokenSource = null;
                    }
                    GrepEngineFactory.UnloadEngines();
                }

                return(new List <GrepSearchResult>(searchResults));
            }
        }
예제 #14
0
파일: GrepCore.cs 프로젝트: dnGrep/dnGrep
        private void Search(string file, SearchType searchType, string searchPattern, GrepSearchOption searchOptions, int codePage)
        {
            try
            {
                ProcessedFile(this, new ProgressStatus(true, processedFilesCount, foundfilesCount, null, file));

                bool isArchive = Utils.IsArchive(file);

                Encoding encoding = Encoding.Default;
                if (codePage > -1)
                {
                    encoding = Encoding.GetEncoding(codePage);
                }
                else if (!isArchive && !Utils.IsBinary(file) && !Utils.IsPdfFile(file))
                {
                    encoding = Utils.GetFileEncoding(file);
                }

                if (Utils.CancelSearch)
                {
                    if (cancellationTokenSource != null)
                    {
                        cancellationTokenSource.Cancel();
                    }
                    return;
                }

                IGrepEngine engine = GrepEngineFactory.GetSearchEngine(file, SearchParams, FileFilter, searchType);

                if (isArchive && engine is ArchiveEngine archiveEngine)
                {
                    archiveEngine.SetSearchOptions(FileFilter, SearchParams);
                    archiveEngine.StartingFileSearch += ArchiveEngine_StartingFileSearch;

                    foreach (var fileSearchResults in archiveEngine.Search(file, searchPattern, searchType, searchOptions, encoding))
                    {
                        if (fileSearchResults != null && fileSearchResults.Count > 0)
                        {
                            AddSearchResults(fileSearchResults);
                        }
                        int hits = fileSearchResults.Where(r => r.IsSuccess).Count();
                        Interlocked.Add(ref foundfilesCount, hits);

                        ProcessedFile(this, new ProgressStatus(false, processedFilesCount, foundfilesCount, fileSearchResults, file));
                    }
                    archiveEngine.StartingFileSearch -= ArchiveEngine_StartingFileSearch;
                }
                else
                {
                    Interlocked.Increment(ref processedFilesCount);

                    var fileSearchResults = engine.Search(file, searchPattern, searchType, searchOptions, encoding).ToList();

                    if (fileSearchResults != null && fileSearchResults.Count > 0)
                    {
                        AddSearchResults(fileSearchResults);
                    }
                    int hits = fileSearchResults.Where(r => r.IsSuccess).Count();
                    Interlocked.Add(ref foundfilesCount, hits);

                    ProcessedFile(this, new ProgressStatus(false, processedFilesCount, foundfilesCount, fileSearchResults, file));
                }

                GrepEngineFactory.ReturnToPool(file, engine);
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Failed in Search");
                AddSearchResult(new GrepSearchResult(file, searchPattern, ex.Message, false));
                if (ProcessedFile != null)
                {
                    List <GrepSearchResult> _results = new List <GrepSearchResult>
                    {
                        new GrepSearchResult(file, searchPattern, ex.Message, false)
                    };
                    ProcessedFile(this, new ProgressStatus(false, processedFilesCount, foundfilesCount, _results, file));
                }
            }
            finally
            {
                if (searchOptions.HasFlag(GrepSearchOption.StopAfterFirstMatch) && searchResults.Count > 0)
                {
                    if (cancellationTokenSource != null)
                    {
                        cancellationTokenSource.Cancel();
                    }
                }
            }
        }
예제 #15
0
파일: GrepCore.cs 프로젝트: dnGrep/dnGrep
        /// <summary>
        /// Searches folder for files whose content matches regex
        /// </summary>
        /// <param name="files">Files to search in. If one of the files does not exist or is open, it is skipped.</param>
        /// <param name="searchRegex">Regex pattern</param>
        /// <returns>List of results. If nothing is found returns empty list</returns>
        public List <GrepSearchResult> Search(IEnumerable <string> files, SearchType searchType, string searchPattern, GrepSearchOption searchOptions, int codePage)
        {
            searchResults.Clear();

            if (files == null)
            {
                return(searchResults);
            }

            if (string.IsNullOrEmpty(searchPattern))
            {
                return(searchResults);
            }

            Utils.CancelSearch = false;

            processedFilesCount = 0;
            foundfilesCount     = 0;

            try
            {
                if (SearchParams.SearchParallel)
                {
                    cancellationTokenSource = new CancellationTokenSource();

                    ParallelOptions po = new ParallelOptions
                    {
                        MaxDegreeOfParallelism = Math.Max(1, Environment.ProcessorCount * 4 / 5),
                        CancellationToken      = cancellationTokenSource.Token
                    };
                    Parallel.ForEach(files, po, f => Search(f, searchType, searchPattern, searchOptions, codePage));
                }
                else
                {
                    foreach (var file in files)
                    {
                        Search(file, searchType, searchPattern, searchOptions, codePage);

                        if (searchOptions.HasFlag(GrepSearchOption.StopAfterFirstMatch) && searchResults.Count > 0)
                        {
                            break;
                        }

                        if (Utils.CancelSearch)
                        {
                            break;
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // expected for stop after first match or user cancel
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Failed in search in files");
            }
            finally
            {
                if (cancellationTokenSource != null)
                {
                    cancellationTokenSource.Dispose();
                    cancellationTokenSource = null;
                }
                GrepEngineFactory.UnloadEngines();
            }

            return(new List <GrepSearchResult>(searchResults));
        }
예제 #16
0
        protected string DoRegexReplace(int lineNumber, int filePosition, string text, string searchPattern, string replacePattern,
                                        GrepSearchOption searchOptions, IEnumerable <GrepMatch> replaceItems)
        {
            RegexOptions regexOptions = RegexOptions.None;

            if (!searchOptions.HasFlag(GrepSearchOption.CaseSensitive))
            {
                regexOptions |= RegexOptions.IgnoreCase;
            }
            if (searchOptions.HasFlag(GrepSearchOption.Multiline))
            {
                regexOptions |= RegexOptions.Multiline;
            }
            if (searchOptions.HasFlag(GrepSearchOption.SingleLine))
            {
                regexOptions |= RegexOptions.Singleline;
            }

            bool isWholeWord = searchOptions.HasFlag(GrepSearchOption.WholeWord);

            if (isWholeWord)
            {
                if (!searchPattern.Trim().StartsWith("\\b"))
                {
                    searchPattern = "\\b" + searchPattern.Trim();
                }
                if (!searchPattern.Trim().EndsWith("\\b"))
                {
                    searchPattern = searchPattern.Trim() + "\\b";
                }
            }

            // Issue #210 .net regex will only match the $ end of line token with a \n, not \r\n or \r
            bool   convertToWindowsNewline = false;
            string searchPatternForReplace = searchPattern;

            if (searchPattern.Contains("$") && text.Contains("\r\n"))
            {
                convertToWindowsNewline = true;
                searchPatternForReplace = searchPattern.Replace("\r\n", "\n");
                replacePattern          = replacePattern.Replace("\r\n", "\n");
            }

            StringBuilder sb      = new StringBuilder();
            int           counter = 0;

            foreach (GrepMatch match in RegexSearchIterator(lineNumber, filePosition, text, searchPattern, searchOptions))
            {
                if (replaceItems.Any(r => match.Equals(r) && r.ReplaceMatch))
                {
                    string matchText       = text.Substring(match.StartLocation - filePosition, match.Length);
                    int    matchTextLength = matchText.Length; // save in case the newline is changed

                    if (convertToWindowsNewline)
                    {
                        matchText = matchText.Replace("\r\n", "\n");
                    }

                    string replaceText = Regex.Replace(matchText, searchPatternForReplace, DoPatternReplacement(matchText, replacePattern), regexOptions);

                    if (convertToWindowsNewline)
                    {
                        replaceText = replaceText.Replace("\n", "\r\n");
                    }

                    sb.Append(text.Substring(counter, match.StartLocation - filePosition - counter));
                    sb.Append(replaceText);

                    counter = match.StartLocation - filePosition + matchTextLength;
                }

                if (Utils.CancelSearch)
                {
                    break;
                }
            }

            sb.Append(text.Substring(counter));

            string result = sb.ToString();

            return(result);
        }
예제 #17
0
        /// <summary>
        /// Searches folder for files whose content matches regex
        /// </summary>
        /// <param name="files">Files to search in. If one of the files does not exist or is open, it is skipped.</param>
        /// <param name="searchRegex">Regex pattern</param>
        /// <returns>List of results. If nothing is found returns empty list</returns>
        public List <GrepSearchResult> Search(IEnumerable <string> files, SearchType searchType, string searchPattern, GrepSearchOption searchOptions, int codePage)
        {
            searchResults.Clear();

            if (files == null)
            {
                return(searchResults);
            }

            Utils.CancelSearch = false;

            if (searchPattern == null || searchPattern.Trim() == "")
            {
                int count = 0;
                foreach (string file in files)
                {
                    count++;
                    ProcessedFile(this, new ProgressStatus(true, searchResults.Count, count, null, file));

                    searchResults.Add(new GrepSearchResult(file, searchPattern, null, Encoding.Default));

                    if ((searchOptions & GrepSearchOption.StopAfterFirstMatch) == GrepSearchOption.StopAfterFirstMatch)
                    {
                        break;
                    }
                    if (Utils.CancelSearch)
                    {
                        break;
                    }
                }

                ProcessedFile(this, new ProgressStatus(false, searchResults.Count, count, searchResults, null));

                return(new List <GrepSearchResult>(searchResults));
            }
            else
            {
                processedFilesCount = 0;
                foundfilesCount     = 0;

                try
                {
                    if (SearchParams.SearchParallel)
                    {
                        cancellationTokenSource = new CancellationTokenSource();

                        ParallelOptions po = new ParallelOptions();
                        po.MaxDegreeOfParallelism = Environment.ProcessorCount * 4 / 5;
                        po.CancellationToken      = cancellationTokenSource.Token;
                        Parallel.ForEach(files, po, f => Search(f, searchType, searchPattern, searchOptions, codePage));
                    }
                    else
                    {
                        foreach (var file in files)
                        {
                            Search(file, searchType, searchPattern, searchOptions, codePage);

                            if (searchOptions.HasFlag(GrepSearchOption.StopAfterFirstMatch) && searchResults.Count > 0)
                            {
                                break;
                            }
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    // expected for stop after first match or user cancel
                }
                catch (Exception ex)
                {
                    logger.Error(ex, "Failed in search in files");
                }
                finally
                {
                    if (cancellationTokenSource != null)
                    {
                        cancellationTokenSource.Dispose();
                        cancellationTokenSource = null;
                    }
                    GrepEngineFactory.UnloadEngines();
                }

                return(new List <GrepSearchResult>(searchResults));
            }
        }
예제 #18
0
        private IEnumerable <GrepMatch> RegexSearchIterator(int lineNumber, int filePosition, string text, string searchPattern, GrepSearchOption searchOptions)
        {
            RegexOptions regexOptions = RegexOptions.None;

            if (!searchOptions.HasFlag(GrepSearchOption.CaseSensitive))
            {
                regexOptions |= RegexOptions.IgnoreCase;
            }
            if (searchOptions.HasFlag(GrepSearchOption.Multiline))
            {
                regexOptions |= RegexOptions.Multiline;
            }
            if (searchOptions.HasFlag(GrepSearchOption.SingleLine))
            {
                regexOptions |= RegexOptions.Singleline;
            }

            bool isWholeWord = searchOptions.HasFlag(GrepSearchOption.WholeWord);

            if (isWholeWord)
            {
                if (!searchPattern.Trim().StartsWith("\\b"))
                {
                    searchPattern = "\\b" + searchPattern.Trim();
                }
                if (!searchPattern.Trim().EndsWith("\\b"))
                {
                    searchPattern = searchPattern.Trim() + "\\b";
                }
            }

            // Issue #210 .net regex will only match the $ end of line token with a \n, not \r\n or \r
            // see https://msdn.microsoft.com/en-us/library/yd1hzczs.aspx#Multiline
            // and http://stackoverflow.com/questions/8618557/why-doesnt-in-net-multiline-regular-expressions-match-crlf
            // must change the Windows and Mac line ends to just the Unix \n char before calling Regex
            if (searchPattern.Contains("$"))
            {
                // if the search pattern has Windows or Mac newlines, they must be converted, too
                searchPattern = searchPattern.Replace("\r\n", "\n");
                searchPattern = searchPattern.Replace('\r', '\n');

                if (lineNumber == -1 && text.Contains("\r\n"))
                {
                    foreach (var match in RegexSearchIteratorSpecial(text, searchPattern, regexOptions))
                    {
                        yield return(match);
                    }

                    yield break;
                }

                if (text.Contains("\r\n"))
                {
                    text = text.Replace("\r\n", "\n");
                }
                else if (text.Contains("\r"))
                {
                    text = text.Replace('\r', '\n');
                }
            }

            var lineEndIndexes = GetLineEndIndexes((initParams.VerboseMatchCount && lineNumber == -1) ? text : null);

            List <GrepMatch> globalMatches = new List <GrepMatch>();
            var matches = Regex.Matches(text, searchPattern, regexOptions, MatchTimeout);

            foreach (Match match in matches)
            {
                if (initParams.VerboseMatchCount && lineEndIndexes.Count > 0)
                {
                    lineNumber = lineEndIndexes.FindIndex(i => i > match.Index) + 1;
                }

                yield return(new GrepMatch(lineNumber, match.Index + filePosition, match.Length));
            }
        }