In my opinion I think you're simply overthinking this towards your Regular Expression in order to accomplish the task at hand. It's always a good idea to keep your expressions as simple and as readable as possible. It's evident that you already realize this.
Grouping is obviously required here since you only want specific data from names specifically related to that data. Since you already know the names you want specific data from this makes things somewhat easier:
Now I don't know what the web page content consists of but we'll cover a couple scenarios. Your situation is most likely the latter of the two.
Scenario 1:
If there are only specific number of lines within the web page content which consist of:
<input type="hidden" name="ip_h" value="8d25cea553b4afe087" />
<input type="hidden" name="lg_h" value="e04c5b67874fd6e28b" />
<input type="hidden" name="_origin" value="https://oauth.site.com" />
<input type="hidden" name="to" value="aHR0cHM6Ly9vYXV0aC52ay5jb20vYXl" />
and the names are always in the same order then you can use a simple regex like this:
"value\\=\"(.*?)\""
which is the same as saying:
Go through the whole string and group everything that is between a substring that looks like value="
and a double quote character (") since the value you want is within double quote marks.
It's now just a matter of iterating through the found items to gather the data:
while (matcher.find()) {
System.out.println(matcher.group(1));
}
Now this wont work very well at all if there are other lines within the web page content that also contains a key titled value=
and its value is also within double quote marks. The regex example above would pull that data out as well which is obviously no good. The regex is just not specific enough which now brings us to the next scenario.
Scenario 2:
In this particular scenario the web page content contains lots of lines that have a key titled value=
and its related data value within double quotation marks ("). We obviously don't want them all so we need to be more specific with our regular expression. Since we know the names related to the name key within the content how about we try:
"(\"ip_h\"|\"lg_h\"|\"to\").*value\\=\"(.*?)\""
Here we're working with two groups and the actual data we want will be contained within the second group. The first group utilizes the RegEx OR operator (|) to keep things simple. What the above Regular Expression is basically saying is:
Work along the entire string, IF you encounter a name of "ip_h" OR a name of "ip_h" OR a name of "to" AND somewhere directly after that name is a substring which looks like value=" THEN grab the data that is between value=" and the next encountered double quotation mark " and put it into Group 2.
It's now just a matter of iterating through the found items to gather the data contained in Group 2:
while (matcher.find()) {
System.out.println(matcher.group(2));
}
If you find that you still need to be more specific that accommodate your Regular Expression to do so. You can just add another group. If you find it's getting to large then place your expression into a String variable if you like.
String regEx = "(\\<input type\\=\"hidden\".*)(\"ip_h\"|\"lg_h\"|\"to\").*value\\=\"(.*?)\"";
Pattern pattern = Pattern.compile(regEx);
Matcher matcher = pattern.matcher(form);
// The required data ca be obtained from Group 3
The following is your code slightly modified:
String form = "123123" +
"<input type=\"hidden\" name=\"ip_h\" value=\"8d25cea553b4afe087\" />\n" +
"<input type=\"hidden\" name=\"lg_h\" value=\"e04c5b67874fd6e28b\" />\n" +
"<input type=\"hidden\" name=\"_origin\" value=\"https://oauth.site.com\" />\n"+
"<input type=\"hidden\" name=\"to\" value=\"aHR0cHM6Ly9vYXV0aC52ay5jb20vYXl\" />\n";
Pattern pattern = Pattern.compile("(\"ip_h\"|\"lg_h\"|\"to\").*value\\=\"(.*?)\"");
Matcher matcher = pattern.matcher(form);
List<String> foundValues = new ArrayList<>();
while (matcher.find()) {
foundValues.add(matcher.group(2));
}
// Display List in Console...
for (int i = 0; i < foundValues.size(); i++) {
System.out.println(foundValues.get(i));
}
// If you want to have all the found items placed
// into a one Dimensional String Array then you can
// use this code:
String[] itemsFound = foundValues.toArray(new String[0]);
// Display Array in Console...
System.out.println();
for (int i = 0; i < itemsFound.length; i++) {
System.out.println(itemsFound[i]);
}