【问题标题】:Extract stuff from text using Regex and Java使用 Regex 和 Java 从文本中提取内容
【发布时间】:2016-10-12 15:14:38
【问题描述】:

我有一些这样的文字:

 //(10,0,'Computer_accessibility','',''),(13,0,'History_of_Afghanistan','',''),(14,0,'Geography_of_Afghanistan','','')

我写了一个模式:

public final static Pattern r_english = Pattern.compile("\\((.*?),(.*?),(.*?),(.*?),(.*?)\\)");

这在 Java 中可以很好地提取 m.group(1)(例如 13)和 m.group(3)(例如 History_of_Afghanistan),其中 m 是一个匹配器。 但是,如果文本是这样的,它就会中断,因为华盛顿,_D.C. (ie. m.group(3)) 里面有一个逗号:

(8543,0,'Washington,_D.C.','',''),(8546,0,'Extermination_camp','','')

有人可以帮助我使用正则表达式来修改它并提取 Washington,_D.C.东西?谢谢

【问题讨论】:

    标签: java regex string text


    【解决方案1】:

    更改您的第三个捕获组以捕获所有内容,直到达到关闭 '。这样可以捕获每个字符(包括您的逗号)。

    更新:为了也允许转义 's,正则表达式看起来像这样。学分归 Pshemo,见 cmets。

    public final static Pattern r_english = Pattern.compile("\\((.*?),(.*?),('(?:[^']|\\')*'),(.*?),(.*?)\\)");
    

    【讨论】:

    • 现在我正在等待来自 OP 的信息,该标题中可能还包含多个 '。但现在看起来还可以。
    • 到目前为止它不在示例输入中:D
    • 顺便说一句,您可能不需要'[^']*?' 中的?(.*?)也可以改成([^,]*)
    • @Knight 在这种情况下,您需要创建一些格式,以便我们确定哪个' 是标题的一部分,哪个' 被视为代表标题结尾的引号。换句话说,您需要引入一些非特殊 ' 的转义机制,例如在其前面加上 \ (但这也意味着 \ 是特殊的,所以就像在字符串文字中一样,您还需要转义它如果你想创建这样的符号),或者像 SQL 那样,用另一个 ' 转义每个文本 ' 它,比如 'Marvin''s_Room'
    • @Knight 在这种情况下,不要使用仅接受非引号字符的[^'],而是尝试编写接受非引号或转义引号。所以尝试将('[^']*') 更改为('(?:[^']|\\')*') \\ 写为\\\\。如果你想知道(?:...)是什么,它被称为非捕获组,它是一个不包含在组树中的组,所以你不能通过group(index)访问它,我这样做是为了不影响你当前组索引。
    【解决方案2】:

    您应该帮助使您的 RegEx 更适合您的案例。 例如:

    ((.*?),(.*?),('.*?'),('.*?'),('.*?'))
    

    我使用了括号 ',此解决方案也与第 3-5 组中的进一步括号无关。

    问候

    【讨论】:

      【解决方案3】:

      您需要更改正则表达式以适合您要检索的所有匹配项,例如:

      /((.*?),(.*?),'(.*?)','(.*?)','(.*?)'\)/g
      

      工作示例@regex101

      您需要将上面的正则表达式翻译/转义为Java兼容的,例如:

      public static String REGEX_PATTERN = "\\((.*?),(.*?),'(.*?)','(.*?)','(.*?)'\\)";
      

      然后,遍历所有匹配以尝试模仿 //g 修饰符,例如:

      while (matcher.find()) {
      }
      

      Java 工作示例:

      package SO40002225;
      
      import java.util.regex.Matcher;
      import java.util.regex.Pattern;
      
      public class Main {
      
          public static String INPUT;
          public static String REGEX_PATTERN;
      
          static {
              INPUT = "(8543,0,'Washington,_D.C.','',''),(8546,0,'Extermination_camp','',''),(8543,0,'Washington,_D.C.','',''),(8546,0,'Extermination_camp','','')";
              REGEX_PATTERN = "\\((.*?),(.*?),'(.*?)','(.*?)','(.*?)'\\)";
          }
      
      
          public static void main(String[] args) {
              String text = INPUT;
      
              Pattern pattern = Pattern.compile(REGEX_PATTERN);
              Matcher matcher = pattern.matcher(text);
      
              while (matcher.find()) {
                  String mg1 = matcher.group(1);
                  String mg2 = matcher.group(2);
                  String mg3 = matcher.group(3);
                  String mg4 = matcher.group(4);
                  String mg5 = matcher.group(5);
      
                  System.out.println("Matching group #1: " + mg1);
                  System.out.println("Matching group #2: " + mg2);
                  System.out.println("Matching group #3: " + mg3);
                  System.out.println("Matching group #4: " + mg4);
                  System.out.println("Matching group #5: " + mg5);
              }
      
          }
      
      }
      

      更新 #1

      删除了在正则表达式中为逗号, 所做的转义,正如 Pshemo 所指出的,, 不是元字符,或者它没有在限制重复中使用量词:{min, max}

      【讨论】:

      • 抱歉,转义, 有什么意义?它不是正则表达式元字符之一(至少不是在这里 - 只有 , 不代表文字的情况是在量词内,如 {min,max}{,max} 但即使这样也没有任何转义的意义)。跨度>
      • @Pshemo,感谢您指出这一点,我完全忘记了这一点。
      猜你喜欢
      • 2011-11-05
      • 1970-01-01
      • 2011-12-10
      • 2015-11-11
      • 2021-10-14
      • 1970-01-01
      • 2017-03-14
      • 1970-01-01
      • 2011-06-14
      相关资源
      最近更新 更多