使用正则表达式从包含换行符的文本中解析字符串

时间:2015-11-30 03:22:45

标签: java regex

鉴于以下文字,我试图在Address:之后解析字符串“TestFile”:

File: TestFile
Branch


        OFFICE INFORMATION
            Address: TestFile
            City: L.A.
            District.: 43
            State: California
            Zip Code: 90210

        DISTRICT INFORMATION
            Address: TestFile2
            ....

据我所知,lookbehinds需要零宽度,因此不允许使用量词,这意味着这不起作用:

(?<=OFFICE INFORMATION\n\s*Address:).*(?=\n)

我可以用这个

(?<=OFFICE INFORMATION\n            Address:).* 

但它取决于一致的间距,这不是动态的,因此不理想。

如何可靠地解析出“TestFile”而不是“TestFile2”,如上例所示。请注意,地址出现两次,但我只需要第一个值。

谢谢

3 个答案:

答案 0 :(得分:1)

你真的不需要在这里使用lookbehind。使用捕获的组获取匹配的文本:

(?:\bOFFICE INFORMATION\s+Address:\s*)(\S+)

RegEx Demo

captured group #1的值为TestFile

JS代码:

var re = /(?:\bOFFICE INFORMATION\s+Address:\s*)(\S+)/; 
var m;
var matches = []; 
if ((m = re.exec(input)) !== null) {
    if (m.index === re.lastIndex)
        re.lastIndex++;
    matches.push(m[1]);
}
console.log(matches);

答案 1 :(得分:1)

使用数组:

// A sample String
String questions = "File: TestFile Branch OFFICE INFORMATION Address: TestFile  City: L.A.   District.: 43       State: California     Zip Code: 90210       DISTRICT INFORMATION           Address: TestFile2";

// An array list to store split elements
ArrayList arr = new ArrayList();

// Split based on colon and spaces.
// Including spaces resolves problems for new lines etc
for(String x : questions.split(":|\\s"))
// Ignore blank elements, so we get a clean array
    if(!x.trim().isEmpty())
        arr.add(x);

这将为您提供一个数组:

[File, TestFile, Branch, OFFICE, INFORMATION, Address, TestFile, City, L.A., District., 43, State, California, Zip, Code, 90210, DISTRICT, INFORMATION, Address, TestFile2]

现在让我们分析一下......假设您需要与Address或元素Address对应的信息。此元素位于数组中的5位置。这意味着元素6就是你想要的。

所以你会这样做:

String address = arr.get(6);

这将返回testFile

类似于City,元素8就是您想要的。计数从0开始。您可以在某种程度上修改我的匹配模式,甚至创建一个循环,让自己更好地完成这项任务。这只是一个暗示。

以下是一个这样的示例循环:

// Every i+1 is the property tag, and every i+2 is the property name for 
// Skip first 6 elements because they are of no real purpose to us
for(int i = 6; i<(arr.size()/2)+6; i+=2)
    System.out.println(arr.get(i));

这给出了以下输出:

TestFile
L.A.
43
California
Code

当然这个循环是未定义的,稍微改进一下你就会得到正确的每一个元素。即使是最后一个元素。或者更好的是,使用ZipCode而不是Zip Code并且不要在它们之间使用空格,你将拥有一个完美的循环,除此之外没什么可做的。)

使用直接正则表达式的优势:您不必为每个元素指定正则表达式。迭代总是更方便自动完成任务。

答案 2 :(得分:0)

见这个

//read input from file
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("D:/tests/sample.txt"))));
StringBuilder string = new StringBuilder();
String line = "";

while((line = reader.readLine()) != null){
    string.append(line);
    string.append("\n");
}
//now string will contain the input as
/*File: TestFile
Branch


        OFFICE INFORMATION
            Address: TestFile
            City: L.A.
            District.: 43
            State: California
            Zip Code: 90210

        DISTRICT INFORMATION
            Address: TestFile2
            ....*/
Pattern regex = Pattern.compile("(OFFICE INFORMATION.*\\r?\\n.*Address:(?<officeAddress>.*)\\r?\\n)");
Matcher regexMatcher = regex.matcher(string.toString());
while (regexMatcher.find()) {
    System.out.println(regexMatcher.group("officeAddress"));//prints TestFile
} 

您可以在需要提取的模式中看到命名组officeAddress