0

我正在尝试编写正确的正则表达式以在 html 中搜索值,但有一些问题。

有一段html:

<div class="inner">
<div class="title">Processing 3-D Secure Transaction</div>
<form autocomplete="off" name="PAResForm" id="PAResForm" action="https://www.alfaportal.ru/" method="POST">
<input name="MD" type="hidden" value="4326381105C3B67B2823E71FD235FFD2"><input value="eJzVWFmvo0iy/iulnkerm9UYt1xdQtJ2pkQdOVw5AW2qGv+is66Q
qrz9LBZ3mCe7mJzYARdloC1dJ/Lk+nQ7KBxxdgtIEgy/Tp/I93MZ5NtZzfdTnPdj5vfz7tex6I/n
4P8DRkGf4Q==" name="PaRes" type="hidden"> 

我正在尝试搜索字符串

<input name="MD" type="hidden" value="4326381105C3B67B2823E71FD235FFD2">

并获得价值

问题是 value 和 name 可以互相替换 例如

<input value="4326381105C3B67B2823E71FD235FFD2" type="hidden" name="MD">

我写了正则表达式模式:

<input.*name=\"MD\"|value=\"([^<>]*?)\"[^<>]*value=\"([^<>]*?)\"|name=\"MD\".*?>

它适用于一些在线正则表达式服务,但不适用于真正的 java。

请帮助正确修改它。

我还编写了简单的命令行工具来测试它。http://pastebin.com/Pzynqrn8

4

7 回答 7

2

我想尝试这样的事情:

<input\s*?(value=['"].*?['"]\s*)|(type=['"].*?["']\s*)|(name=['"].*?['"]\s*)\>
于 2013-10-21T08:24:39.047 回答
2

有很多用于 HTML 解析的工具。我认为你不应该忽视它们。在这里讨论过。

于 2013-10-21T08:29:59.273 回答
2

我不知道如何在 Java 中做到这一点,但我强烈建议使用适当的文档对象模型工具等。

在 PHP 中,我会这样做:

$xml = new DomDocument();
$xml->loadXml($yourHTMLHere);
$xpath = new DOMXPath($xml);
$node = $xpath
    ->evaluate('//form[@name="PAResForm"]//input[@name="MD"]')
    ->item(0);
$yourValueIsHere = $node->getAttribute('value');

5 行,完全可读,不关心属性顺序。Java 可以肯定地做同样的事情,只需搜索适当的类。

并且不要用正则表达式解析不规则语言。Html 不是常规语言。

于 2013-10-21T08:40:29.757 回答
1

我会在这样的模式中使用前瞻:

<input(?=[^>]+?name="MD")[^>]+?value="([A-Z0-9]+)"

你基本上是说你正在寻找一个<input>带有MDname的元素。这就是前瞻:) ,它不消耗任何字符,但确保您的属性存在。然后,您只需匹配第一个捕获组中的值:。(?=[^>]+?name="MD")namevalue([A-Z0-9]+)

以自由间距模式编写模式可能会有所帮助:

<input               # opening input tag
(?=[^>]+?name="MD")  # lookahead looking for the presence of the name attribute
[^>]+?               # anything (whitespace, other attributes) up to ...
value="([A-Z0-9]+)"  # the value attribute and its value

[更新]请注意,使用适当的 HTML 解析器来解析 HTML 几乎总是更好 - 这就是它们的优点。在这种情况下,我认为使用正则表达式很好。请记住下一个必须维护您的代码并做出负责任决定的人。

于 2013-10-21T08:27:59.343 回答
1

一如既往,总是,总是在处理 HTML 时:使用解析器。正则表达式无法胜任这项任务,因为技术原因在一篇著名的帖子中被解释得要死。

Java 有jSoup,它非常容易创建一个小的、简单且可维护的代码来满足您的需求。

Document doc = Jsoup.parse(str);
Element input = doc.select("input[name='MD']").first();

if (input != null) {
    String value = input.attr("value");
    // now do something with it
}

现在将这三行与所有那些毛茸茸的正则表达式答案进行比较,想想它们是多么难以维护和不安全,它们需要多少解释,以及当 HTML 更改时如何从头开始完全重写它们。计算您尝试为自己找到解决方案的时间,并确定 regex 在 HTML 方面是否值得。

于 2013-10-21T14:16:16.360 回答
0

只要您的元素具有这些属性,它并不难:

    public static void main(String[] args) {
        Pattern p = Pattern.compile("<input(?:\\s+|name=\"MD\"|type=\"hidden\"|value=\"([^\"]+)\")+");
        Matcher m = p.matcher("<input name=\"MD\" type=\"hidden\" value=\"4326381105C3B67B2823E71FD235FFD2\">");
        if (m.find()) {
            System.out.println(m.group(1));
        }
    }
于 2013-10-21T13:39:26.177 回答
-1

最后我通过添加另一个模式解决了这个问题。起初我正在寻找一个类似<input ... name='MD' ... />模式的字符串".*?(<input[^<>]*name=\\\"MD\\\"[^<>]*>).*?",然后我正在寻找一个带有模式的结果字符串中的值".*?value=\\\"(.*?)\\\""

谢谢大家的帮助

于 2013-10-21T10:15:57.970 回答