问题如下:

数字与英文结合在一起检索,出现高亮重复问题

如:检索“220”则

关于同意220kV佛山变电站#1、#2主变报废的批复 .txt 检索“220kv”则 关于同意220220kV佛山变电站#1、#2主变报废的批复 .txt 高亮采用的是索引时记录Term的位置,高亮处理采用TermPositionVector termFreqVector = (TermPositionVector)ireader.getTermFreqVector(doc, fieldname);方式,其中主要代码如下: QueryParser queryParser = new QueryParser(Version.LUCENE_30,fieldname,queryAnalyzer);
     Query query = queryParser.parse(keyWordLc);
     Highlighter highlighter = new Highlighter(new SimpleHTMLFormatter(
       "<font color=/"red/">", "</font>"), new QueryScorer(
         query));
     highlighter.setTextFragmenter(new SimpleFragmenter(50));
      
     TermPositionVector termFreqVector = (TermPositionVector)ireader.getTermFreqVector(doc, fieldname);
     /**   
      * 注意这里最好设为true,虽然会影响性能,但是避免出现:
      * 文档题名为:索引测试新建文档1.txt
               * 查看tokens结果:[(1,8,9), (1.txt,8,13), (文档,6,8), (新建,4,6), (测试,2,4), (索引,0,2), (txt,10,13)]
               * 这样高亮显示的时候<font color="red">索引测试新建文档</font>1.txt
               * 因为高亮显示的方法里是按位置信息,当当前匹配的term小于前面最大的最后位置时才去高亮,
               * 不然则在最后获取到最小匹配的term的首位置到最后匹配的term的末位置的字符串全部高亮起来了。
      */
           TokenStream tokenStream = TokenSources.getTokenStream(termFreqVector,true);  
          
           String content = hitDoc.get(fieldname);
           String result = highlighter.getBestFragments(tokenStream, content, 5,"...");   通过调试跟踪,paoding分词器对“220kv”会分词为“220   kv    220kv”,而通过Lucene提供的lucene-highlighter-3.0.2.jar、lucene-memory-3.0.2.jar

解决方法是修改lucene-highlighter-3.0.2.jar中Highlighter类,代码如下:

public final TextFragment[] getBestTextFragments(
  TokenStream tokenStream,
  String text,
  boolean mergeContiguousFragments,
  int maxNumFragments)
  throws IOException, InvalidTokenOffsetsException
 {
  ArrayList<TextFragment> docFrags = new ArrayList<TextFragment>();
  StringBuilder newText=new StringBuilder();
  
     TermAttribute termAtt = tokenStream.addAttribute(TermAttribute.class);
     OffsetAttribute offsetAtt = tokenStream.addAttribute(OffsetAttribute.class);
     tokenStream.addAttribute(PositionIncrementAttribute.class);
     tokenStream.reset();
    
  TextFragment currentFrag = new TextFragment(newText,newText.length(), docFrags.size());
  TokenStream newStream = fragmentScorer.init(tokenStream);
  if(newStream != null) {
    tokenStream = newStream;
  }
  fragmentScorer.startFragment(currentFrag);
  docFrags.add(currentFrag);FragmentQueue fragQueue = new FragmentQueue(maxNumFragments);try
  {String tokenText;
   int startOffset;
   int endOffset;
   int lastEndOffset = 0;
   int lastStartOffset = 0;  //用来记录当前所取的字符串起点位置textFragmenter.start(text, tokenStream);TokenGroup tokenGroup=new TokenGroup(tokenStream);for (boolean next = tokenStream.incrementToken(); next && (offsetAtt.startOffset()< maxDocCharsToAnalyze);
         next = tokenStream.incrementToken())
   {
    if( (offsetAtt.endOffset()>text.length())
     ||
     (offsetAtt.startOffset()>text.length())
     )      
    {
     throw new InvalidTokenOffsetsException("Token "+ termAtt.term()
       +" exceeds length of provided text sized "+text.length());
    }
    if((tokenGroup.numTokens>0)&&(tokenGroup.isDistinct()))
    {
     //the current token is distinct from previous tokens -
     // markup the cached token group info
     startOffset = tokenGroup.matchStartOffset;
     endOffset = tokenGroup.matchEndOffset;
     
     //用下面两行替代代码tokenText = text.substring(startOffset, endOffset);
     //解决“数字+英文或英文+数字”格式关键词出现高亮重复问题,如:检索“220KV”会高亮“220220KV”
     lastStartOffset = Math.max(startOffset, lastEndOffset);
     tokenText = text.substring(lastStartOffset, endOffset);
     
     String markedUpText=formatter.highlightTerm(encoder.encodeText(tokenText), tokenGroup);
     //store any whitespace etc from between this and last group
     if (startOffset > lastEndOffset)
      newText.append(encoder.encodeText(text.substring(lastEndOffset, startOffset)));
     newText.append(markedUpText);
     lastEndOffset=Math.max(endOffset, lastEndOffset);
     
     tokenGroup.clear();//check if current token marks the start of a new fragment
     if(textFragmenter.isNewFragment())
     {
      currentFrag.setScore(fragmentScorer.getFragmentScore());
      //record stats for a new fragment
      currentFrag.textEndPos = newText.length();
      currentFrag =new TextFragment(newText, newText.length(), docFrags.size());
      fragmentScorer.startFragment(currentFrag);
      docFrags.add(currentFrag);
     }
    }tokenGroup.addToken(fragmentScorer.getTokenScore());//    if(lastEndOffset>maxDocBytesToAnalyze)
//    {
//     break;
//    }
   }
   currentFrag.setScore(fragmentScorer.getFragmentScore());if(tokenGroup.numTokens>0)
   {
    //flush the accumulated text (same code as in above loop)
    startOffset = tokenGroup.matchStartOffset;
    endOffset = tokenGroup.matchEndOffset;
    tokenText = text.substring(startOffset, endOffset);
    String markedUpText=formatter.highlightTerm(encoder.encodeText(tokenText), tokenGroup);
    //store any whitespace etc from between this and last group
    if (startOffset > lastEndOffset)
     newText.append(encoder.encodeText(text.substring(lastEndOffset, startOffset)));
    newText.append(markedUpText);
    lastEndOffset=Math.max(lastEndOffset,endOffset);
   }//Test what remains of the original text beyond the point where we stopped analyzing
   if (
//     if there is text beyond the last token considered..
     (lastEndOffset < text.length())
     &&
//     and that text is not too large...
     (text.length()<= maxDocCharsToAnalyze)
    )    
   {
    //append it to the last fragment
    newText.append(encoder.encodeText(text.substring(lastEndOffset)));
   }currentFrag.textEndPos = newText.length();//sort the most relevant sections of the text
   for (Iterator<TextFragment> i = docFrags.iterator(); i.hasNext();)
   {
    currentFrag = i.next();//If you are running with a version of Lucene before 11th Sept 03
    // you do not have PriorityQueue.insert() - so uncomment the code below
    /*
         if (currentFrag.getScore() >= minScore)
         {
          fragQueue.put(currentFrag);
          if (fragQueue.size() > maxNumFragments)
          { // if hit queue overfull
           fragQueue.pop(); // remove lowest in hit queue
           minScore = ((TextFragment) fragQueue.top()).getScore(); // reset minScore
          }
         }
    */
    //The above code caused a problem as a result of Christoph Goller's 11th Sept 03
    //fix to PriorityQueue. The correct method to use here is the new "insert" method
    // USE ABOVE CODE IF THIS DOES NOT COMPILE!
    fragQueue.insertWithOverflow(currentFrag);
   }//return the most relevant fragments
   TextFragment frag[] = new TextFragment[fragQueue.size()];
   for (int i = frag.length - 1; i >= 0; i--)
   {
    frag[i] = fragQueue.pop();
   }//merge any contiguous fragments to improve readability
   if(mergeContiguousFragments)
   {
    mergeContiguousFragments(frag);
    ArrayList<TextFragment> fragTexts = new ArrayList<TextFragment>();
    for (int i = 0; i < frag.length; i++)
    {
     if ((frag[i] != null) && (frag[i].getScore() > 0))
     {
      fragTexts.add(frag[i]);
     }
    }
    frag= fragTexts.toArray(new TextFragment[0]);
   }return frag;}
  finally
  {
   if (tokenStream != null)
   {
    try
    {
     tokenStream.close();
    }
    catch (Exception e)
    {
    }
   }
  }
 }

解决数字和英文字母结合检索出现高亮重复问题相关推荐

  1. Xshell vim使用右侧数字键盘时数字变成英文字母的解决办法

    在通过Xshell连接公司服务器进行工作时发现一个小问题,使用右侧数字键盘时数字的时候,数字变成英文字母了 如下: 123456789变成了yxwvutsrq 并且还自动换行,当然不使用右侧数字键就不 ...

  2. 【转】解决长串英文字母显示不能自动换行的问题和td中汉字自动换行 CSS强制不换行

    解决长串英文字母显示不能自动换行的问题和td中汉字自动换行 && CSS强制不换行 例如:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa不 ...

  3. placeholder=请输入用户名(六位数字加英文字母)

    placeholder="请输入用户名(六位数字加英文字母)" 转载于:https://www.cnblogs.com/nc-blog/p/4122768.html

  4. C# 判断输入的字符串是否只包含数字和英文字母

    /// <summary>/// 判断输入的字符串是否只包含数字和英文字母/// </summary>/// <param name="input"& ...

  5. 分别统计其中数字、英文字母和其它字符的个数

    从键盘输入20个字符,存放在一个字符数组中,然后分别统计其中数字.英文字母和其它字符的个数.( 其中字母在字符的值在65 – 90,97 – 122 为字母,字符 #include<stdio. ...

  6. Pb数字变成英文字母金额

    Pb数字变成英文字母金额 在pb中,想把阿拉伯数字的金额转成英文字母的金额,实现如下效果: 那么先建立一个函数:f_numberToEnglishAmt() 下面是建立函数的语句,大家可以复制下来,创 ...

  7. java treemap字母排序_Java TreeMap对数字,英文字母,汉字等排序例子

    首页 > 基础教程 > 集合框架 > TreeMap类 Java TreeMap对数字,英文字母,汉字等排序例子 1. 对于一些简单的数字,英文字母等排序 TreeMap hm = ...

  8. 2020年全国高校计算机能力挑战赛C++初赛程序设计题2:九键拼音中数字与英文字母成对应关系:2--abc, 3-def, 4-ghi, 5--jkl, 6--mno, 7--pqrs, 8--tuv

    2020年全国高校计算机能力挑战赛C++初赛程序设计题2:九键拼音中数字与英文字母成对应关系:2–abc, 3-def, 4-ghi, 5–jkl, 6–mno, 7–pqrs, 8–tuv, 9–w ...

  9. python matplotlib绘图、混淆矩阵 汉字字体、数字、英文字母的设置

    最近在写一篇文章的时候,文章对图片格式有要求:图中汉字用宋体六号.数字和英文字母用新罗马字体,这些都需要在一张图中表现出来.经过一番查找摸索,现归纳整理如下: 对坐标轴设置 现假设有如下要求:在一张图 ...

最新文章

  1. Python实现微信防撤回
  2. js修改style中某个属性_JS 和 CSS 交互的 5 种方法
  3. JsonBuilder初出茅庐
  4. 懒汉式,同步代码块线程不安全
  5. beyond唱片_如何数字化您的唱片
  6. Android中动态获取Drawable中的图片
  7. extjs 前后端分离_为什么我不喜欢「前后端分离」(个人观点,欢迎来喷)
  8. 一个 38 岁程序员的中年危机
  9. 高薪诚聘游戏引擎研发,有意者请与我联系!
  10. Spring整合Struts2,Hibernate的xml方式
  11. 用计算机解一元二次,请简述如何用科学计算器解一元二次方程
  12. 【源码】基于PMSG的风力发电机组仿真与建模
  13. 数据库界的《延禧攻略》来了,不看你就输了
  14. 39 个奇葩代码注释,看完笑哭了
  15. 如何用小程序玩转裂变?你要的小程序裂变营销都在这里
  16. GVINS / VINS-mono运行报错:undefined symbol: _ZN6google21kLogSiteUninitializedE,重新安装ceres可以解决
  17. [词根词缀]fact/fug/fuse/词源知识F的内容
  18. 安装R语言(Rstudio、R、RTools)
  19. GSM6.10转码与wav文件保存
  20. GlobalMapper20如何更快速的浏览影像(mbt)【tif转mbt】

热门文章

  1. 全球及中国生物识别技术产业应用趋势及投资风险分析报告2021-2027年
  2. C语言自己认为理解有难度的或者容易犯错的知识
  3. 解密一个量化对冲基金开发人员的工作内容
  4. 学计算机的ctrl,学会这些电脑快捷键,瞬间成为电脑高手
  5. 华为发布《智能世界2030》报告,多维探索未来十年趋势
  6. ionic4学习笔记11-某东项目热门商品展示
  7. 跟女神表白用计算机,终于跟女神表白了,她听后没说什么
  8. php 短信验证 云之讯,python3.7实现云之讯、聚合短信平台的短信发送功能
  9. 为什么说用PHP开发大型系统令人不爽
  10. 库卡机器人坐标手势_在工具坐标系中移动库卡机器人