Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用于在不被单引号或双引号包围时使用空格拆分字符串的正则表达式_Java_Regex_Split - Fatal编程技术网

Java 用于在不被单引号或双引号包围时使用空格拆分字符串的正则表达式

Java 用于在不被单引号或双引号包围时使用空格拆分字符串的正则表达式,java,regex,split,Java,Regex,Split,我不熟悉正则表达式,非常感谢您的帮助。我试图组合一个表达式,该表达式将使用所有不被单引号或双引号包围的空格拆分示例字符串。我的最后一次尝试是这样的:(?!”不太有效。它在引号前的空格上分裂 输入示例: This is a string that "will be" highlighted when your 'regular expression' matches something. 期望输出: This is a string that will be highlighted when y

我不熟悉正则表达式,非常感谢您的帮助。我试图组合一个表达式,该表达式将使用所有不被单引号或双引号包围的空格拆分示例字符串。我的最后一次尝试是这样的:
(?!”
不太有效。它在引号前的空格上分裂

输入示例:

This is a string that "will be" highlighted when your 'regular expression' matches something.
期望输出:

This
is
a
string
that
will be
highlighted
when
your
regular expression
matches
something.

请注意,
“将”
“正则表达式”
保留单词之间的空格。

搜索字符串、抓取每个部分可能比拆分字符串更容易

原因是,您可以在
之前和之后的空格处将其拆分为“
”。但是,我想不出任何方法来指定忽略拆分内部的空格

(不是真正的Java)


此外,捕获单引号可能会导致以下问题:

"Foo's Bar 'n Grill"

//=>

"Foo"
"s Bar "
"n"
"Grill"
String.split()
在这里没有帮助,因为无法区分引号内的空格(不拆分)和引号外的空格(拆分)。
Matcher.lookingAt()
可能是您需要的:

String str = "This is a string that \"will be\" highlighted when your 'regular expression' matches something.";
str = str + " "; // add trailing space
int len = str.length();
Matcher m = Pattern.compile("((\"[^\"]+?\")|('[^']+?')|([^\\s]+?))\\s++").matcher(str);

for (int i = 0; i < len; i++)
{
    m.region(i, len);

    if (m.lookingAt())
    {
        String s = m.group(1);

        if ((s.startsWith("\"") && s.endsWith("\"")) ||
            (s.startsWith("'") && s.endsWith("'")))
        {
            s = s.substring(1, s.length() - 1);
        }

        System.out.println(i + ": \"" + s + "\"");
        i += (m.group(0).length() - 1);
    }
}

我可以合理地确定,仅使用正则表达式是不可能的。检查其他标记中是否包含某些内容是一种解析操作。这似乎与尝试使用正则表达式解析XML的问题相同——无法正确完成。通过反复应用非贪婪,匹配带引号字符串的非全局正则表达式,一旦你找不到其他任何东西,就在空格处拆分它……这有很多问题,包括跟踪所有子字符串的原始顺序。你最好只编写一个非常简单的函数,在字符串上迭代并取出你想要的标记。

有几个关于StackOverflow的问题,它们在不同的上下文中使用正则表达式来解决相同的问题。例如:

更新:处理单引号和双引号字符串的示例正则表达式。参考:

使用一个快速的Perl代码段对此进行了测试,输出结果如下所示。如果空字符串或仅空白字符串位于引号之间(不确定是否需要)


请注意,这确实在匹配的值中包含引号字符本身,不过您可以通过字符串替换来删除引号字符,或者修改正则表达式使其不包含引号字符。我将把这作为读者的练习或另一张海报暂时留着,因为凌晨2点太晚了,再也无法处理正则表达式;)

如果您想允许的话字符串中的转义引号,可以使用如下内容:

(?:(['"])(.*?)(?<!\\)(?>\\\\)*\1|([^\s]+))
(?:(['”])(.*?(\\\)*\1 |([^\s]+)
带引号的字符串为第2组,单个不带引号的单词为第3组


您可以在这里的各种字符串上尝试它:或者

我不明白为什么所有其他人都建议使用如此复杂的正则表达式或如此长的代码。本质上,您希望从字符串中获取两种类型的内容:不是空格或引号的字符序列,以及以引号开头和结尾的字符序列,两种引号之间没有引号。您可以使用以下正则表达式轻松匹配这些内容:

[^\s"']+|"([^"]*)"|'([^']*)'
我添加了捕获组,因为您不希望列表中有引号

这段Java代码构建列表,如果捕获组匹配,则添加捕获组以排除引号,如果捕获组不匹配,则添加整个正则表达式匹配(匹配了一个不带引号的单词)

List matchList=new ArrayList();
Pattern regex=Pattern.compile(“[^\\s\”]+\”([^\”]*)\“\”([^']*)”)”;
Matcher regexMatcher=regex.Matcher(subjectString);
while(regexMatcher.find()){
if(regexMatcher.group(1)!=null){
//添加不带引号的双引号字符串
添加(regexMatcher.group(1));
}else if(regexMatcher.group(2)!=null){
//添加不带引号的单引号字符串
添加(regexMatcher.group(2));
}否则{
//添加不带引号的单词
add(regexMatcher.group());
}
} 
如果您不介意在返回的列表中使用引号,可以使用更简单的代码:

List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("[^\\s\"']+|\"[^\"]*\"|'[^']*'");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
    matchList.add(regexMatcher.group());
} 
List matchList=new ArrayList();
Pattern regex=Pattern.compile(“[^\\s\”]+\“[^\”]*\“[^']*\”);
Matcher regexMatcher=regex.Matcher(subjectString);
while(regexMatcher.find()){
add(regexMatcher.group());
} 

(?我喜欢Marcus的方法,但是,我修改了它,允许文本靠近引号,并支持“和”引号字符。例如,我需要a=“some value”来不将其拆分为[a=,“some value”]


(?对Jan的公认答案进行了一些希望有用的调整:

(['"])((?:\\\1|.)+?)\1|([^\s"']+)
  • 允许在带引号的字符串中使用转义引号
  • 避免重复单引号和双引号的模式;这还简化了在需要时添加更多引号符号(以牺牲一个或多个捕获组为代价)

Jan Goyvaerts的正则表达式是迄今为止我找到的最好的解决方案,但也创建了空(null)匹配,他在他的程序中排除了空匹配。这些空匹配也出现在正则表达式测试程序(例如rubular.com)中。 如果将搜索转到四周(首先查找带引号的部分,然后再查找空格分隔的单词),则可以使用以下命令立即执行搜索:

("[^"]*"|'[^']*'|[\S]+)+

简的方法很好,但这里有另一个记录在案

如果您确实想按照标题中所述进行拆分,将引号保留在
中将是“
正则表达式”
,那么您可以使用此方法,它是直接从

正则表达式:

'[^']*'|\"[^\"]*\"|( )
左侧的两个替换项匹配完整的
“引号内的字符串”
“双引号内的字符串”
。我们将忽略这些匹配项。右侧匹配并捕获组1的空格,我们知道它们是右空格,因为
List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("[^\\s\"']+|\"([^\"]*)\"|'([^']*)'");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
    if (regexMatcher.group(1) != null) {
        // Add double-quoted string without the quotes
        matchList.add(regexMatcher.group(1));
    } else if (regexMatcher.group(2) != null) {
        // Add single-quoted string without the quotes
        matchList.add(regexMatcher.group(2));
    } else {
        // Add unquoted word
        matchList.add(regexMatcher.group());
    }
} 
List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("[^\\s\"']+|\"[^\"]*\"|'[^']*'");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
    matchList.add(regexMatcher.group());
} 
(?<!\G".{0,99999})\s|(?<=\G".{0,99999}")\s
(?<!\\G\\S{0,99999}[\"'].{0,99999})\\s|(?<=\\G\\S{0,99999}\".{0,99999}\"\\S{0,99999})\\s|(?<=\\G\\S{0,99999}'.{0,99999}'\\S{0,99999})\\s"
(['"])((?:\\\1|.)+?)\1|([^\s"']+)
("[^"]*"|'[^']*'|[\S]+)+
'[^']*'|\"[^\"]*\"|( )
import java.util.*;
import java.io.*;
import java.util.regex.*;
import java.util.List;

class Program {
public static void main (String[] args) throws java.lang.Exception  {

String subject = "This is a string that \"will be\" highlighted when your 'regular expression' matches something.";
Pattern regex = Pattern.compile("\'[^']*'|\"[^\"]*\"|( )");
Matcher m = regex.matcher(subject);
StringBuffer b= new StringBuffer();
while (m.find()) {
    if(m.group(1) != null) m.appendReplacement(b, "SplitHere");
    else m.appendReplacement(b, m.group(0));
}
m.appendTail(b);
String replaced = b.toString();
String[] splits = replaced.split("SplitHere");
for (String split : splits) System.out.println(split);
} // end main
} // end Program
    String str = "This is a string that \"will be\" highlighted when your 'regular expression' matches something";
    String ss[] = str.split("\"|\'");
    for (int i = 0; i < ss.length; i++) {
        if ((i % 2) == 0) {//even
            String[] part1 = ss[i].split(" ");
            for (String pp1 : part1) {
                System.out.println("" + pp1);
            }
        } else {//odd
            System.out.println("" + ss[i]);
        }
    }
string input= "This is a string that \"will be\" highlighted when your 'regular expression' matches <something random>";

List<string> list1 = 
                Regex.Matches(input, @"(?<match>\w+)|\""(?<match>[\w\s]*)""|'(?<match>[\w\s]*)'|<(?<match>[\w\s]*)>").Cast<Match>().Select(m => m.Groups["match"].Value).ToList();

foreach(var v in list1)
   Console.WriteLine(v);
This
is
a
string
that
will be
highlighted
when
your
regular expression 
matches
something random
using System.Text.RegularExpressions;

var args = Regex.Matches(command, "[^\\s\"']+|\"([^\"]*)\"|'([^']*)'").Cast<Match>
().Select(iMatch => iMatch.Value.Replace("\"", "").Replace("'", "")).ToArray();
String s = "This is a string that \"will be\" highlighted when your 'regular expression' matches something.";
String[] split = s.split( "(?<!(\"|').{0,255}) | (?!.*\\1.*)" );