如果字符串具有以下预测格式:
value = "hello and good morning"
其中"(引号)也可以是'(单引号),并且结束字符('或")将与开始字符相同。我想匹配引号之间的字符串。
bvalues*=s*(["'])([^1]*)1
(两个s允许在=号附近有空格)
第一个"捕获组"(在第一对括号内)-应该匹配开头的引语,应该是'或"然后-我应该允许任何数量的字符不是在第一组中捕获的字符,然后我期望在组中捕获的字符(封闭引号)。
(所需的字符串应该在第二个捕获组中捕获)。
但这行不通。
这样做:
bvalues*=s*(['"])([^"']*)["']
但是我想确保前后引号(双引号或单引号)是相同的
编辑
目标基本上是获得锚的开始标记,锚的class属性中包含了特定的类名,并且我想涵盖类属性中包含(')或(")的罕见情况。
根据这里的所有建议,我使用了以下模式:
<s*bab[^<>]+bclasss*=s*("|'|\"|\')(?:(?!1).)*s*classnames*(?:(?!1).)*1[^>]*>
含义:
找一个打开标签的标志。
允许任何空格。
查找字 a.
允许任何非结束标记。
查找"class (any spaces) = (any spaces)"
获取起始引号,下列之一:("或'或"或')。
艾伦·摩尔的回答是:允许开头引号以外的任何字符。
查找classname
允许除开始引号以外的任何字符。
找出与开头相同的结尾引语。
允许任何关闭标记字符。
找到结束标记字符。
不使用反向字符类,而是使用反向forward:
bvalues*=s*(["'])(?:(?!1).)*1
(?:(?!1).)*
一次消耗一个字符,之后的 forward已经确认该字符不是捕获组(["''])
匹配的字符。一个字符类,无论是否否定,一次只能匹配一个字符。就regex引擎所知,1
可以表示任意数量的字符,在这种情况下,没有办法使它相信1
只包含"
或'
。因此,您必须使用更通用(但可读性较差)的解决方案。
您可以使用:
bvalues*=s*(['"])(.*?)1
查看
在不知道您需要这些信息的情况下(甚至不知道您使用这个正则表达式的语言或工具),我可以推荐许多路径。
使用这些字符串:
value = "hello and good morning"
value = 'hola y buenos dias'
value = 'how can I say "goodbye" so soon?'
value = 'why didn't you say "hello" to me this morning?'
value = "Goodbye! Please don't forget to write!"
value = 'Goodbye! Please don't forget to write!'
这个表达式:
"((\"|[^"])*)"|'((\'|[^'])*)'
将匹配以下字符串:
"hello and good morning"
'hola y buenos dias'
'how can I say "goodbye" so soon?'
'why didn't you say "hello" to me this morning?'
"Goodbye! Please don't forget to write!"
'Goodbye! Please don't forget to write!'
允许"other"类型的引号或相同类型的引号,当转义为单个时。带引号的字符串的内容属于第1组或第3组。您可以通过获取第一个(或最后一个)字符来确定使用了哪种类型的引号。
如果你需要其中一些东西在特定的匹配组中,请给出更具体的例子(包括不应该工作的东西,但看起来可能很接近)
请询问您是否愿意走这条路,并需要更多的帮助
回答这个问题如何在忽略集合中使用数值引用?
这里的,因为它被标记为与这个完全相同。
不能在类中指定捕获组。
可以做的是在否定断言中指定字符,如
(["'])((?:(?!1)[Ss])*)(1)
( ["'] ) # (1)
( # (2 start)
(?:
(?! 1 )
[Ss]
)*
) # (2 end)
( 1 ) # (3)
请注意,在原始帖子[^char]
通常匹配换行符
也可以,但由于这是JavaScript(旧的JS),点不能被使用。
使用[Ss]
代替,它匹配任何字符。
我是在寻找模式匹配的帮助时看到这篇文章的
value="long text with "quoted values" and more"
目前Alan Moore给出的最佳答案非常好,但是没有考虑引号的转义。所以感谢Alan,当允许用:
bvalues*=s*(["'])(?:(?!(?<!\)1).)*1
奖金信息
也许你在这里寻找的模式与我的目的相同,因此我也将分享我的最终解决方案。我必须匹配几个键值对,格式与html相同——属性通常列在节点中,如:one="first" two="second"
。
下面的正则表达式将匹配它,并将捕获组命名为key
和value
:
b(?P<key>[^=s]*)s*=s*(["'])(?P<value>(?:(?!(?<!\)2).)*)2
当我们为CMS Effcore编写Markdown解析器时,我们尝试了不同的变体以确保最高的速度。这些变体如下所示:
替换示例:
"markdown *text*"
:
"markdown <em>text</em>"
PHP Code #1 for characters "*"one_answers";_"(贪婪模式):preg_replace('%'.'([*_])'.'(?<phrase>.+?)'.'\1'.'%sS', '<em>$2<em>', $text);
PHP Code #2 for characters "*"one_answers";_"(反向引用否定):
preg_replace('%'.'([*_])'.'(?<phrase>(?:(?!\1).){1,})'.'\1'.'%sS', '<em>$2<em>', $text);
PHP代码#3 for single character "*"(字符类中的否定):preg_replace('%'.'([*])'.'(?<phrase>[^*]{1,})'.'[*]'.'%sS', '<em>$2<em>', $text);
Case #1 ("贪心模式")比Case #2 ("反引用中的否定")快。
在1000000次迭代上测试:
- 0.0245740413665秒。
- 3.3793921470642秒。