name-parser/src/main/java/org/gbif/nameparser/ParsingJob.java
/**
   * Tries to parse a name string with the full regular expression.
   * In very few, extreme cases names with very long authorships might cause the regex to never finish or take hours
   * we run this parsing in a separate thread that can be stopped if it runs too long.
   * @param name
   * @return  true if the name could be parsed, false in case of failure
   */
Tries to parse a name string with the full regular expression.
In very few, extreme cases names with very long authorships might cause the regex to never finish or take hours
we run this parsing in a separate thread that can be stopped if it runs too long.
@param name
@return  true if the name could be parsed, false in case of failure
Tries to parse a name string with the full regular expression . In very few extreme cases names with very long authorships might cause the regex to never finish or take hours we run this parsing in a separate thread that can be stopped if it runs too long . @param name @return true if the name could be parsed false in case of failure
private boolean parseNormalisedName(String name) throws InterruptedException {
    LOG.debug("Parse normed name string: {}", name);
    Matcher matcher = matcherInterruptable(NAME_PATTERN, name);
    if (matcher.find()) {
      if (StringUtils.isBlank(matcher.group(23))) {
        pn.setState(ParsedName.State.COMPLETE);
      } else {
        LOG.debug("Partial match with unparsed remains \"{}\" for: {}", matcher.group(23), name);
        pn.setState(ParsedName.State.PARTIAL);
        pn.addUnparsed(matcher.group(23).trim());
      }
      if (LOG.isDebugEnabled()) {
        logMatcher(matcher);
      }
      setUninomialOrGenus(matcher, pn);
      boolean bracketSubrankFound = false;
      if (matcher.group(2) != null) {
        bracketSubrankFound = true;
        pn.setInfragenericEpithet(StringUtils.trimToNull(matcher.group(2)));
      } else if (matcher.group(4) != null) {
        setRank(matcher.group(3));
        pn.setInfragenericEpithet(StringUtils.trimToNull(matcher.group(4)));
      }
      setEpithetQualifier(NamePart.SPECIFIC, matcher.group(5));
      pn.setSpecificEpithet(StringUtils.trimToNull(matcher.group(6)));
      if (matcher.group(7) != null && matcher.group(7).length() > 1 && !matcher.group(7).contains("null")) {
        pn.setRank(Rank.INFRASUBSPECIFIC_NAME);
      }
      setEpithetQualifier(NamePart.INFRASPECIFIC, matcher.group(8));
      setRank(matcher.group(9));
      pn.setInfraspecificEpithet(StringUtils.trimToNull(matcher.group(10)));
      if (matcher.group(11) != null) {
        setRank(matcher.group(11));
        pn.setInfraspecificEpithet(matcher.group(12));
      }
      if (matcher.group(13) != null) {
        setRank(matcher.group(13));
        ignoreAuthorship = true;
      }
      lookForIrregularRankMarker();
      if (pn.isIndetermined()) {
        ignoreAuthorship = true;
      }
      if (!ignoreAuthorship && matcher.group(14) != null) {
        pn.setCombinationAuthorship(parseAuthorship(matcher.group(19), matcher.group(20), matcher.group(22)));
        if (matcher.group(21) != null) {
          pn.setSanctioningAuthor(matcher.group(21));
        }
        pn.setBasionymAuthorship(parseAuthorship(matcher.group(15), matcher.group(16), matcher.group(18)));
        if (bracketSubrankFound && infragenericIsAuthor(pn)) {
          pn.setBasionymAuthorship(parseAuthorship(null, pn.getInfragenericEpithet(), null));
          pn.setInfragenericEpithet(null);
          if (pn.getGenus() != null && pn.getSpecificEpithet() == null && pn.getInfraspecificEpithet() == null) {
            pn.setUninomial(pn.getGenus());
            pn.setGenus(null);
          }
          LOG.debug("swapped subrank with bracket author: {}", pn.getBasionymAuthorship());
        }
      }
      return true;
    }
    return false;
  }
private boolean parseNormalisedName ( String name ) throws InterruptedException { LOG . debug ( "Parse normed name string: {}" , name ) ; Matcher matcher = matcherInterruptable ( NAME_PATTERN , name ) ; if ( matcher . find ( ) ) { if ( StringUtils . isBlank ( matcher . group ( 23 ) ) ) { pn . setState ( ParsedName . State . COMPLETE ) ; } else { LOG . debug ( "Partial match with unparsed remains \"{}\" for: {}" , matcher . group ( 23 ) , name ) ; pn . setState ( ParsedName . State . PARTIAL ) ; pn . addUnparsed ( matcher . group ( 23 ) . trim ( ) ) ; } if ( LOG . isDebugEnabled ( ) ) { logMatcher ( matcher ) ; } setUninomialOrGenus ( matcher , pn ) ; boolean bracketSubrankFound = false ; if ( matcher . group ( 2 ) != null ) { bracketSubrankFound = true ; pn . setInfragenericEpithet ( StringUtils . trimToNull ( matcher . group ( 2 ) ) ) ; } else if ( matcher . group ( 4 ) != null ) { setRank ( matcher . group ( 3 ) ) ; pn . setInfragenericEpithet ( StringUtils . trimToNull ( matcher . group ( 4 ) ) ) ; } setEpithetQualifier ( NamePart . SPECIFIC , matcher . group ( 5 ) ) ; pn . setSpecificEpithet ( StringUtils . trimToNull ( matcher . group ( 6 ) ) ) ; if ( matcher . group ( 7 ) != null && matcher . group ( 7 ) . length ( ) > 1 && ! matcher . group ( 7 ) . contains ( "null" ) ) { pn . setRank ( Rank . INFRASUBSPECIFIC_NAME ) ; } setEpithetQualifier ( NamePart . INFRASPECIFIC , matcher . group ( 8 ) ) ; setRank ( matcher . group ( 9 ) ) ; pn . setInfraspecificEpithet ( StringUtils . trimToNull ( matcher . group ( 10 ) ) ) ; if ( matcher . group ( 11 ) != null ) { setRank ( matcher . group ( 11 ) ) ; pn . setInfraspecificEpithet ( matcher . group ( 12 ) ) ; } if ( matcher . group ( 13 ) != null ) { setRank ( matcher . group ( 13 ) ) ; ignoreAuthorship = true ; } lookForIrregularRankMarker ( ) ; if ( pn . isIndetermined ( ) ) { ignoreAuthorship = true ; } if ( ! ignoreAuthorship && matcher . group ( 14 ) != null ) { pn . setCombinationAuthorship ( parseAuthorship ( matcher . group ( 19 ) , matcher . group ( 20 ) , matcher . group ( 22 ) ) ) ; if ( matcher . group ( 21 ) != null ) { pn . setSanctioningAuthor ( matcher . group ( 21 ) ) ; } pn . setBasionymAuthorship ( parseAuthorship ( matcher . group ( 15 ) , matcher . group ( 16 ) , matcher . group ( 18 ) ) ) ; if ( bracketSubrankFound && infragenericIsAuthor ( pn ) ) { pn . setBasionymAuthorship ( parseAuthorship ( null , pn . getInfragenericEpithet ( ) , null ) ) ; pn . setInfragenericEpithet ( null ) ; if ( pn . getGenus ( ) != null && pn . getSpecificEpithet ( ) == null && pn . getInfraspecificEpithet ( ) == null ) { pn . setUninomial ( pn . getGenus ( ) ) ; pn . setGenus ( null ) ; } LOG . debug ( "swapped subrank with bracket author: {}" , pn . getBasionymAuthorship ( ) ) ; } } return true ; } return false ; }
Tries to parse a name string with the full regular expression.
Tries to parse a name string with the full regular expression .
// the match can be the genus part of an infrageneric, bi- or trinomial, the uninomial or even the infrageneric epithet! // 4 parted name, so its below subspecies // microbial ranks // indet rank markers // make sure (infra)specific epithet is not a rank marker! // entire authorship, not stored in ParsedName // #19/20/21/22 authorship (ex/auth/sanct/year) // sanctioning author // #15/16/17/18 basionym authorship (ex/auth/sanct/year) // rather an author than a infrageneric rank. Swap in case of monomials // check if we need to move genus to uninomial