我正在使用以下正则表达式在文本文件中查找网址:
/http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+/
输出以下内容:
http://rda.ucar.edu/datasets/ds117.0/.
http://rda.ucar.edu/datasets/ds111.1/.
http://www.discover-earth.org/index.html).
http://community.eosdis.nasa.gov/measures/).
理想情况下,他们会打印出来:
http://rda.ucar.edu/datasets/ds117.0/
http://rda.ucar.edu/datasets/ds111.1/
http://www.discover-earth.org/index.html
http://community.eosdis.nasa.gov/measures/
关于如何调整我的正则表达式的任何想法?
提前谢谢!
更新 - 文本示例如下:
this is a test http://rda.ucar.edu/datasets/ds117.0/. and I want this to be copied over http://rda.ucar.edu/datasets/ds111.1/. http://www.discover-earth.org/index.html). http://community.eosdis.nasa.gov/measures/).
答案 0 :(得分:1)
所以对于你在这里的网址: https://regex101.com/r/uSlkcQ/4
模式说明:
协议(例如https://
)
^[A-Za-z]{3,9}:(?://)
寻找经常性.[-;:&=+\$,\w]+
- 班级(www.sub.domain.com)
(?:[\-;:&=\+\$,\w]+\.?)+`
寻找定期/[\-;:&=\+\$,\w\.]+
(/some.path/to/somewhere)
(?:\/[\-;:&=\+\$,\w\.]+)+
现在,针对您的特殊情况:使用负向前瞻确保最后一个字符不是圆点或括号
(?!\.|\)).
然后是完整的模式
^[A-Za-z]{3,9}:(?://)(?:[\-;:&=\+\$,\w]+\.?)+(?:\/[\-;:&=\+\$,\w\.]+)+(?!\.|\)).
答案 1 :(得分:1)
现有的正则表达式有一些改进或改变的方法可以让它起作用:
http[s]?
可以更改为https?
。他们是完全相同的。没有必要将s
放在自己的角色类[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]
您可以缩短整个内容并组合字符类,而不是在它们之间使用|
。这不仅可以提高性能,还可以将某些范围组合到现有的字符类标记中。简化这一点,我们得到[a-zA-Z0-9$-_@.&+!*\(\),]
a-zA-Z0-9_
与\w
相同。所以我们可以替换字符类中的那些来获取[\w$-@.&+!*\(\),]
$-_
。这会创建一个范围,因此它实际上包含了ASCII表上$
和_
之间的所有内容。这将导致不需要的字符匹配:$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
。有几个选项可以解决这个问题:
[-\w$@.&+!*\(\),]
将-
放在角色类的开头[\w$@.&+!*\(\),-]
将-
放在角色类的末尾[\w$\-@.&+!*\(\),]
退出-
,以便\-
改为(
和)
:[\w$@.&+!*(),-]
[0-9a-fA-F][0-9a-fA-F]
您不需要指定[0-9a-fA-F]
两次。只需使用如下量词:[0-9a-fA-F]{2}
(?:%[0-9a-fA-F][0-9a-fA-F])
这里实际上并不需要非捕获组,因此我们可以删除它(它增加了正则表达式引擎需要执行的另一个步骤,这是不必要的)因此,简化现有正则表达式的结果如下:
https?://(?:[$\w@.&+!*(),-]|%[0-9a-fA-F]{2})+
现在您已经注意到它与/
不匹配,因此我们需要将其添加到角色类中。您的正则表达式最初与此匹配,因为它具有不正确的范围$-_
。
https?://(?:[$\w@.&+!*(),/-]|%[0-9a-fA-F]{2})+
不幸的是,即使进行了此更改,它仍会在结尾处与).
匹配。这是因为你的正则表达式在/
之后没有被告知停止匹配。即使实现这一点,现在也会导致它与index.html
之类的文件名不匹配。因此需要一个更好的解决方案。如果你给我几天时间,我正在开发一个与URL匹配的功能齐全的RFC兼容正则表达式。我想,在此期间,我至少会解释为什么你的正则表达式没有像你期望的那样工作。
答案 2 :(得分:1)
这将修剪包含跟踪字符) .
import re
regx= re.compile(r'(?m)[\.\)]+$')
print(regx.sub('', your_output))
这个正则表达式似乎可以从原始示例文本中提取URL
。
https?:[\S]*\/(?:\w+(?:\.\w+)?)?
Demo ,,,(从https?:[\S]*\/
编辑)
Python脚本可能是这样的
ss=""" this is a test http://rda.ucar.edu/datasets/ds117.0/. and I want this to be copied over http://rda.ucar.edu/datasets/ds111.1/. http://www.discover-earth.org/index.html). http://community.eosdis.nasa.gov/measures/). """
regx= re.compile(r'https?:[\S]*\/(?:\w+(?:\.\w+)?)?')
for m in regx.findall(ss):
print(m)
答案 3 :(得分:0)
感谢大家的回复。一位同事最终帮助我。这是解决方案:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">