【问题标题】:Regex, find semicolons not within block comments ( /* */)正则表达式,查找不在块注释中的分号( /* */)
【发布时间】:2018-07-08 21:27:17
【问题描述】:

我正在尝试查找不在块 cmets 中的分号以拆分为字符串数组 (Java)。

这是我目前使用的正则表达式:

(?<!\/\*.\s\S);(?!.*\s*\S*\*\/)

我正在尝试使用否定的后向和前瞻来完成此操作,但除了最后一个在块注释中的单独行上重复的分号之外的所有分号都被发现。然而,块注释中的最后一个分号不是。

我正在使用https://regexr.com/(选择PCRE regex引擎)来测试上面的正则表达式。

我正在使用以下示例代码对此进行测试:

SELECT * FROM TEST;

SELECT * FROM TEST;

/* 
SELECT * FROM TEST;
SELECT * FROM TEST;
SELECT * FROM TEST;
SELECT * FROM TEST;
SELECT * FROM TEST;
*/
SELECT * FROM TEST; 

我还使用了以下正则表达式,它似乎得到了与我上面的正则表达式相同的结果,除了两个前瞻:

(?!\/\*\s*\S*)(;)(?!\s*\S*.*\*\/)

此外,似乎通过在正则表达式末尾添加 \s*\S*.* 到前瞻中,我可以“破解”这个问题,因为每个添加似乎都可以解决其中一个问题块注释中的分号。例如,如果我在最后一次预读中有两次 '\s*\S*.*',我最多可以在块注释中注释掉两个分号。

基本上,我在这个地方到处都是......

总结一下,我只是想在块 cmets 之外获取查询的分号。

如您所知,我对正则表达式不是很有经验,不幸的是,我几乎整天都在为此苦苦挣扎。任何指针将不胜感激!谢谢!

这是一个方便的链接,可将您带到我在 regexr 中的正则表达式,并加载了示例代码:https://regexr.com/3junf

【问题讨论】:

  • 这很容易做到,只需要一个循环和一个/*的测试。
  • Regex 是这个工作的错误工具。首先删除 cmets,然后查找分号。但是,字符串中的分号呢?你真正需要的是一个 SQL 解析器。正则表达式是编程的“锤子”。当有人给你一把锤子时,一切看起来都像钉子。
  • 感谢您的建议!

标签: java regex regex-lookarounds


【解决方案1】:

这将回答您的直接问题(有点,我没有使用正则表达式),但 Jim 是对的,如果您正在解析 SQL,您需要一个解析器。

public class BlockComment {

   static StringReader test = new StringReader ( "This is test1;\nThis is test2;\n" +
           "/*This is test3;\nThis is test4;*/\nThis is test5;" );

   public static void main( String[] args ) throws IOException {

      BufferedReader br = new BufferedReader( new SkipBlockComments( test ) );
      String line;
      while( (line = br.readLine()) != null ) {
         System.out.println( line );
      }

   }

   public static class SkipBlockComments extends FilterReader {

      private boolean inBlock;

      public SkipBlockComments( Reader r ) {
         super( r );
         if( !markSupported() ) throw new IllegalArgumentException();
      }

      @Override
      public int read() throws IOException {
         for( ;; ) {
            int character = super.read();
            if( !inBlock ) {
               if( character == '/' && nextCharEquals( '*' ) ) {
                  inBlock = true;
               } else {
                  return character;
               }
            } else {
               if( character == '*' && nextCharEquals( '/' ) ) {
                  inBlock = false;
               }
            }
         }
      }

      private boolean nextCharEquals( char c ) throws IOException {
         mark( 1 );
         if( super.read() == c )
            return true;
         reset();
         return false;
      }


      @Override
      public int read( char[] buf, int start, int length ) throws IOException {
         int c = read();
         if( c == -1 ) return -1;
         buf[start] = (char) c;
         return 1;
      }

      @Override
      public int read( char[] buf ) throws IOException {
         return read( buf, 0, 1 );
      }
   }
}

【讨论】:

    猜你喜欢
    • 2014-01-27
    • 1970-01-01
    • 2012-05-22
    • 2013-04-16
    • 1970-01-01
    • 2013-08-14
    • 2016-07-15
    • 2013-07-02
    相关资源
    最近更新 更多