我有多语言字符串,格式如下:
这是英语
语言的顺序并不总是相同的,也不是所有语言都总是可用的。
我正在尝试提取一个特定的语言字符串,但没有成功。语言字符串包含HTML和任何类型的特殊字符、空格、换行符、制表符等。
假设我想提取英语部分;我需要一个正则表达式,它能够匹配[en]部分之后的所有内容(换行、回车、特殊字符、制表符等),直到新语言字符串开始:([a-z]{2})
这不起作用:法语字符串也会返回,如果西班牙语字符串在过去的位置,则不会返回任何字符串。
/'[es']((.|'n|'t|'r)*)('[([a-z]{2})'])/u
我无法为以下内容编写正则表达式:"[es]后面不是括号内两个字母或字符串末尾的任何内容"
任何帮助都将不胜感激!
真正的问题是贪婪匹配。有几种方法可以解决这个问题。懒惰匹配:
/'[es']((?:.|'n|'t|'r)*?)'[([a-z]{2})']/u
和负面表情广告:
/'[es']((?:(?!'[([a-z]{2})'])(?:.|'n|'t|'r))*)/u
您知道,Regex引擎是贪婪,这意味着它捕获尽可能多的令牌,回溯直到它有一个匹配的字符串-通常的说法是引擎返回尽可能大的捕获。您可以使用lazy匹配器(后面跟着?
的任何匹配器-因此是??
、*?
、+?
等),它会反转匹配行为并捕获尽可能少的数据,慢慢地捕获更多数据,直到匹配为止。您还可以使用前瞻性来确保匹配的通配符不包括分隔符字符串。
也可以使用s
修改器来强制。以匹配所有内容,包括换行符(它已经匹配't
字符。
/'[es'](.*?)'[([a-z]{2})']/su
提醒一下这个故事,<罢工>如果大力神战斗,你会失败的如果你的字符串中有任何看起来像语言代码的东西,但不是-这个regex将失败。罢工>
单击此处查看匹配情况。
FrankieTheKneMan对贪婪和懒惰行为之间的区别做出了很好的解释。
要利用贪婪行为而不进行回溯(或进行非常有限的回溯),可以使用否定字符类:
/'[es]([^[]*)/u
(注意,你不需要s修饰符,因为你不使用点。)
在情况下:但是,先例模式不允许在要匹配的内容中使用左方括号。如果您检查每个[
不是一个语言标签的开头,就可以解决这个问题:
/'[es]((?>[^[]+|'[(?![a-z]{2}]))*)/u